From 7af06e05f09b695f3a082884ca4c212afcb91069 Mon Sep 17 00:00:00 2001 From: John Goerzen Date: Fri, 1 Jun 2007 04:39:20 -0500 Subject: [PATCH] Import upstream gpsbabel version 1.3.3 Imported gpsbabel-1.3.3.tar.gz into Mercurial repository --- AUTHORS | 3 + Makefile.in | 105 +- alan.c | 938 ++ an1.c | 6 +- axim_gpb.c | 18 +- bcr.c | 129 +- cet.c | 1 + coastexp.c | 159 +- configure | 39 +- configure.in | 18 +- contrib/correctCoordinates.pl | 0 copilot.c | 212 +- csv_util.c | 84 +- csv_util.h | 6 +- defs.h | 42 +- discard.c | 34 +- dmtlog.c | 15 +- easygps.c | 163 +- filter_vecs.c | 2 +- garmin.c | 26 +- garmin_fs.c | 24 +- garmin_fs.h | 2 +- garmin_tables.c | 235 +- garmin_txt.c | 221 +- gbfile.c | 286 +- gbfile.h | 2 + gbser_posix.c | 1 + gbser_win.c | 1 + gbtypes.h | 2 + gbversion.h | 8 + gbversion.h.in | 8 + gdb.c | 188 +- geo.c | 38 +- globals.c | 1 + glogbook.c | 42 +- google.c | 14 + gpsbabel.html | 1891 +-- gpx.c | 171 +- gpxval | 11 +- gtm.c | 416 +- gtrnctr.c | 8 +- hiketech.c | 40 +- holux.c | 8 +- hsa_ndv.c | 76 +- html.c | 2 +- igc.c | 2 +- ignrando.c | 76 +- internal_styles.c | 59 +- jeeps/.cvsignore | 1 + jeeps/gpsapp.c | 52 +- jeeps/gpsapp.h | 1 + jeeps/gpslibusb.c | 1 + jeeps/gpsserial.c | 1 + jeeps/gpsusbstub.c | 2 +- jeeps/gpsusbwin.c | 5 + kml.c | 42 +- lowranceusr.c | 16 +- magnav.c | 4 +- magproto.c | 51 +- main.c | 70 +- mapsend.c | 281 +- mapsource.c | 2 +- mingw/include/expat.h | 1222 +- mingw/lib/README | 2 + mingw/lib/libexpat.a | Bin 39988 -> 48984 bytes mingw/lib/libexpat.def | 64 + mingw/libexpat.dll | Bin 122773 -> 143360 bytes mingw/testo | 0 mkshort.c | 14 + msroute.c | 7 +- msvc/Expat/libexpat.dll | Bin msvc/GPSBabel-msvc7.sln | 21 + msvc/GPSBabel-msvc7.vcproj | 2493 +++ msvc/GPSBabel.vcproj | 120 +- msvc/config.h | 52 +- nmea.c | 252 +- palmdoc.c | 2 +- pathaway.c | 2 +- pcx.c | 121 +- position.c | 157 +- psitrex.c | 89 +- queue.c | 2 + raymarine.c | 476 + reference/alantrl.gpx | 2448 +++ reference/alantrl.trl | Bin 0 -> 266240 bytes reference/alanwpr.gpx | 381 + reference/alanwpr.wpr | Bin 0 -> 65536 bytes reference/cet/cet-sample.gpx | 6 +- reference/coastexp.ref | 2 +- reference/coastexp.ref2 | 76 +- reference/coastexp.ref3 | 105 +- reference/coastexp.ref4 | 97 +- reference/compegps-wpt.gpx | 2 +- reference/cototestmarker.gpx | 2 +- reference/dusky.trk | 0 reference/earth-expertgps.kml | 7 +- reference/earth-gc.kml | 7 +- reference/easygps.loc | Bin reference/expertgps.rwf | 2270 +++ reference/fugawi.time.ref.txt | 2 +- reference/garmin_symbols.gpx | 4620 ++++++ reference/gc/GC7FA4.gpx | 4 +- reference/gc/GCGCA8.gpx | 4 +- reference/gdb-sample-v3.gdb | Bin 0 -> 69073 bytes reference/gdb-sample.gpx | 2 +- reference/geonet-sample.gpx | 2 +- reference/gn-targets.gpx | 2 +- reference/gpsutil-1.pcx | 23 + reference/hiketech.gpx | 2 +- reference/igc1.gpx | 2 +- reference/igc1_gpx.out | 2 +- reference/igc2_gpx.out | 2 +- reference/magnav.pdb | Bin 1160 -> 1160 bytes reference/mapsource.mps | Bin reference/mps-empty.mps | Bin reference/psitwpts.txt | 0 reference/raymarine-sample.gpx | 83 + reference/raymarine-sample.rwf | 164 + reference/route/bcr-sample.gpx | 2 +- reference/route/compegps-rte.gpx | 2 +- reference/route/cst-sample.gpx | 2 +- reference/route/mag_pdb-sample.gpx | 2 +- reference/route/msroute-sample.gpx | 2 +- reference/route/nmn4-sample.gpx | 2 +- reference/route/psitrtes.txt | 0 reference/route/route.mps | Bin reference/route/stmwpp-route.gpx | 2 +- reference/route/stmwpp-route.txt | 18 +- reference/route/tef_xml.sample.gpx | 2 +- reference/sample.gtm.gz | Bin 0 -> 56931 bytes reference/tpo-sample3.gpx | 2 +- reference/track/axim-sample.gpx | 2 +- reference/track/compegps-trk.gpx | 2 +- reference/track/dmtlog-sample.gpx | 55 +- reference/track/i65.anr | Bin reference/track/ignrando-sample.gpx | 2 +- reference/track/interptrack.gpx | 2 +- reference/track/kompass.tk | 64 + reference/track/nmea.gpx | 2 +- reference/track/pathaway.gpx | 2 +- reference/track/psittrks.txt | 0 reference/track/stmwpp-track.gpx | 108 +- reference/track/tinterptrack.gpx | 2 +- reference/track/tpo-sample1.gpx | 2 +- reference/track/trackfilter-sdistance.gpx | 2 +- reference/track/trackfilter-sdistance2.gpx | 2 +- reference/track/trackfilter.gpx | 2 +- reference/track/tracks.gpx | 265 +- reference/track/vitosmt_t.gpx | 476 +- reference/transform-rte.gpx | 2 +- reference/transform-wpt.gpx | 2 +- reference/unicsv.gpx | 2 +- reference/vitosmt.gpx | 476 +- reference/wbt-200.gpx | 2 +- route.c | 1 - shapelib/.cvsignore | 1 + shapelib/shpopen.c | 8 +- smplrout.c | 1 + stmsdf.c | 8 +- stmwpp.c | 12 +- style/gpsdrivetrack.style | 5 +- style/kompass_tk.style | 18 + style/kompass_wp.style | 26 + style/tabsep.style | 2 + tef_xml.c | 32 +- test-all | 208 + testo | 41 +- text.c | 2 +- tiger.c | 4 +- tools/cleardebug | 0 tools/mkcapabilities.in | 8 + tools/mkrpm | 117 +- torture_test | 0 trackfilter.c | 59 +- transform.c | 7 +- unicsv.c | 17 +- util.c | 129 +- vcf.c | 26 +- vecs.c | 35 +- vitosmt.c | 5 +- waypt.c | 3 +- wbt-200.c | 1 - wfff_xml.c | 2 +- win32/GPSBabelGUI.exe | Bin 1002504 -> 1002504 bytes win32/gui-2/GPSBabelGUI.dof | 4 +- win32/gui-2/GPSBabelGUI.res | Bin 1748 -> 1748 bytes win32/gui-2/filter.dfm | Bin 8761 -> 8943 bytes win32/gui-2/filter.pas | 79 +- win32/gui-2/locale/es/LC_MESSAGES/default.po | 904 ++ win32/gui-2/locale/es/LC_MESSAGES/delphi.po | 12734 ++++++++++++++++ win32/gui-2/locale/es/LC_MESSAGES/gpsbabel.po | 396 + win32/gui-2/options.pas | 8 +- xcsv.c | 44 +- xmldoc/babelpdf.xsl | 82 + xmldoc/chapters/build.xml | 12 +- xmldoc/chapters/datums.xml | 2 +- xmldoc/chapters/garmin_icons.xml | 165 +- xmldoc/chapters/preface.xml | 27 +- xmldoc/chapters/styles.xml | 55 +- xmldoc/chapters/use.xml | 90 +- xmldoc/filters/arc.xml | 2 +- xmldoc/filters/discard.xml | 2 +- xmldoc/filters/duplicate.xml | 2 +- xmldoc/filters/interpolate.xml | 6 +- xmldoc/filters/nuketypes.xml | 2 +- xmldoc/filters/options/duplicate-all.xml | 2 +- xmldoc/filters/options/duplicate-correct.xml | 2 +- xmldoc/filters/options/track-merge.xml | 2 +- xmldoc/filters/options/track-move.xml | 2 +- xmldoc/filters/options/track-sdistance.xml | 20 +- xmldoc/filters/options/track-split.xml | 22 +- xmldoc/filters/options/track-start.xml | 2 +- xmldoc/filters/options/transform-del.xml | 9 + xmldoc/filters/options/transform-rte.xml | 11 + xmldoc/filters/options/transform-trk.xml | 13 + xmldoc/filters/options/transform-wpt.xml | 11 + xmldoc/filters/polygon.xml | 6 +- xmldoc/filters/position.xml | 2 +- xmldoc/filters/radius.xml | 2 +- xmldoc/filters/simplify.xml | 2 +- xmldoc/filters/stack.xml | 36 +- xmldoc/filters/transform.xml | 4 +- xmldoc/formats/alantrl.xml | 29 + xmldoc/formats/alanwpr.xml | 30 + xmldoc/formats/an1.xml | 4 +- xmldoc/formats/arc.xml | 8 + xmldoc/formats/axim_gpb.xml | 2 +- xmldoc/formats/baroiq.xml | 2 +- xmldoc/formats/bcr.xml | 2 +- xmldoc/formats/cambridge.xml | 6 +- xmldoc/formats/cetus.xml | 2 +- xmldoc/formats/coastexp.xml | 2 +- xmldoc/formats/compegps.xml | 2 +- xmldoc/formats/copilot.xml | 7 +- xmldoc/formats/coto.xml | 2 +- xmldoc/formats/cst.xml | 6 +- xmldoc/formats/csv.xml | 14 +- xmldoc/formats/easygps.xml | 5 +- xmldoc/formats/fugawi.xml | 4 +- xmldoc/formats/garmin.xml | 52 +- xmldoc/formats/garmin301.xml | 7 +- xmldoc/formats/garmin_txt.xml | 12 +- xmldoc/formats/gcdb.xml | 8 +- xmldoc/formats/gdb.xml | 3 +- xmldoc/formats/geo.xml | 2 +- xmldoc/formats/geoniche.xml | 5 +- xmldoc/formats/glogbook.xml | 6 +- xmldoc/formats/google.xml | 2 +- xmldoc/formats/gpilots.xml | 8 +- xmldoc/formats/gpsutil.xml | 10 +- xmldoc/formats/gpx.xml | 5 + xmldoc/formats/gtrnctr.xml | 3 +- xmldoc/formats/holux.xml | 2 +- xmldoc/formats/html.xml | 13 +- xmldoc/formats/igc.xml | 28 +- xmldoc/formats/kml.xml | 2 +- xmldoc/formats/kompass_tk.xml | 8 + xmldoc/formats/kompass_wp.xml | 7 + xmldoc/formats/lowranceusr.xml | 2 +- xmldoc/formats/magellan.xml | 5 +- xmldoc/formats/magellan1.xml | 10 +- xmldoc/formats/magellanx.xml | 8 +- xmldoc/formats/maggeo.xml | 5 +- xmldoc/formats/magnav.xml | 4 +- xmldoc/formats/mapconverter.xml | 2 +- xmldoc/formats/mapsend.xml | 2 +- xmldoc/formats/nmea.xml | 19 +- xmldoc/formats/openoffice.xml | 4 +- xmldoc/formats/options/an1-nogc.xml | 2 +- xmldoc/formats/options/an1-road.xml | 2 +- xmldoc/formats/options/bcr-index.xml | 2 +- .../formats/options/bcr-prefer_shortnames.xml | 4 + xmldoc/formats/options/compegps-index.xml | 2 +- xmldoc/formats/options/garmin-get_posn.xml | 2 +- xmldoc/formats/options/garmin-power_off.xml | 2 +- xmldoc/formats/options/garmin_txt-grid.xml | 50 + xmldoc/formats/options/igc-timeadj.xml | 4 +- xmldoc/formats/options/ignrando-index.xml | 2 +- xmldoc/formats/options/nmn4-index.xml | 2 +- xmldoc/formats/options/stmsdf-index.xml | 4 +- xmldoc/formats/options/stmwpp-index.xml | 2 +- xmldoc/formats/options/tiger-genurl.xml | 8 +- xmldoc/formats/options/tpg-datum.xml | 5 +- xmldoc/formats/options/xcsv-datum.xml | 4 + xmldoc/formats/palmdoc.xml | 2 +- xmldoc/formats/pcx.xml | 7 +- xmldoc/formats/psp.xml | 28 +- xmldoc/formats/raymarine.xml | 7 + xmldoc/formats/s_and_t.xml | 5 +- xmldoc/formats/saplus.xml | 2 +- xmldoc/formats/shape.xml | 15 + xmldoc/formats/stmsdf.xml | 4 +- xmldoc/formats/tef.xml | 2 +- xmldoc/formats/text.xml | 2 +- xmldoc/formats/tmpro.xml | 4 +- xmldoc/formats/tomtom.xml | 2 +- xmldoc/formats/unicsv.xml | 2 +- xmldoc/formats/wbt-bin.xml | 4 +- xmldoc/formats/wbt.xml | 2 +- xmldoc/formats/xmap.xml | 5 +- xmldoc/formats/xmap2006.xml | 4 +- xmldoc/formats/xmapwpt.xml | 21 +- xmldoc/gpsbabel_man.xml | 2 +- xmldoc/makedoc.in | 8 +- xmldoc/old/readme.xml | 6 +- xmlgeneric.c | 49 +- xmlgeneric.h | 20 +- zlib/.cvsignore | 1 + 308 files changed, 35128 insertions(+), 4371 deletions(-) create mode 100644 alan.c mode change 100644 => 100755 contrib/correctCoordinates.pl create mode 100644 gbversion.h create mode 100644 gbversion.h.in create mode 100644 jeeps/.cvsignore create mode 100644 mingw/lib/README create mode 100755 mingw/lib/libexpat.def mode change 100644 => 100755 mingw/testo mode change 100644 => 100755 msvc/Expat/libexpat.dll create mode 100644 msvc/GPSBabel-msvc7.sln create mode 100644 msvc/GPSBabel-msvc7.vcproj create mode 100644 raymarine.c create mode 100644 reference/alantrl.gpx create mode 100644 reference/alantrl.trl create mode 100644 reference/alanwpr.gpx create mode 100644 reference/alanwpr.wpr mode change 100644 => 100755 reference/dusky.trk mode change 100644 => 100755 reference/easygps.loc create mode 100644 reference/expertgps.rwf create mode 100644 reference/garmin_symbols.gpx create mode 100644 reference/gdb-sample-v3.gdb create mode 100644 reference/gpsutil-1.pcx mode change 100644 => 100755 reference/mapsource.mps mode change 100644 => 100755 reference/mps-empty.mps mode change 100644 => 100755 reference/psitwpts.txt create mode 100644 reference/raymarine-sample.gpx create mode 100644 reference/raymarine-sample.rwf mode change 100644 => 100755 reference/route/psitrtes.txt mode change 100644 => 100755 reference/route/route.mps create mode 100644 reference/sample.gtm.gz mode change 100644 => 100755 reference/track/i65.anr create mode 100644 reference/track/kompass.tk mode change 100644 => 100755 reference/track/psittrks.txt create mode 100644 shapelib/.cvsignore create mode 100644 style/kompass_tk.style create mode 100644 style/kompass_wp.style create mode 100755 test-all mode change 100644 => 100755 tools/cleardebug mode change 100644 => 100755 torture_test create mode 100644 win32/gui-2/locale/es/LC_MESSAGES/default.po create mode 100644 win32/gui-2/locale/es/LC_MESSAGES/delphi.po create mode 100644 win32/gui-2/locale/es/LC_MESSAGES/gpsbabel.po create mode 100644 xmldoc/babelpdf.xsl create mode 100644 xmldoc/filters/options/transform-del.xml create mode 100644 xmldoc/filters/options/transform-rte.xml create mode 100644 xmldoc/filters/options/transform-trk.xml create mode 100644 xmldoc/filters/options/transform-wpt.xml create mode 100644 xmldoc/formats/alantrl.xml create mode 100644 xmldoc/formats/alanwpr.xml create mode 100644 xmldoc/formats/kompass_tk.xml create mode 100644 xmldoc/formats/kompass_wp.xml create mode 100644 xmldoc/formats/options/bcr-prefer_shortnames.xml create mode 100644 xmldoc/formats/options/garmin_txt-grid.xml create mode 100644 xmldoc/formats/options/xcsv-datum.xml create mode 100644 xmldoc/formats/raymarine.xml create mode 100644 xmldoc/formats/shape.xml create mode 100644 zlib/.cvsignore diff --git a/AUTHORS b/AUTHORS index 1ad113d95..c28c51c21 100644 --- a/AUTHORS +++ b/AUTHORS @@ -22,11 +22,13 @@ Other contributors and helpers: * Claus Broch * Curtis E. Mills * Dave Pawson +* Daniel Diaz Quintero * Eric Cloninger * Etienne Tasse * Frank Warmerdam * Fredie Kern * Gary Paulson +* Gunar Megger * Gustavo Niemeyer * Harald Nordius * HSA Systems, Sven Dowideit @@ -39,6 +41,7 @@ Other contributors and helpers: * Josh McKee * Justin Broughton * Kjeld Jensen +* Lilian Morinon * Mark Bradley * Oyvind Kaurstad * P. Rosen diff --git a/Makefile.in b/Makefile.in index fcfc1a08b..19284ecec 100644 --- a/Makefile.in +++ b/Makefile.in @@ -9,8 +9,8 @@ RELEASE=@PACKAGE_RELEASE@ VERSIOND=$(VERSD)$(RELEASE) VERSIONU=$(VERSU)$(RELEASE) -DOCVERSION=development DOCVERSION=@PACKAGE_VERSION@ +# DOCVERSION=development CC=@CC@ EXEEXT=@EXEEXT@ @@ -36,7 +36,8 @@ OUTPUT_SWITCH=-o # GBCFLAGS=$(EXTRA_CFLAGS) $(DEBUGGING) -I. -I@srcdir@/coldsync \ $(OPTIMIZATION) @CFLAGS@ LDFLAGS=$(EXTRA_LDFLAGS) @LDFLAGS@ -DESTDIR=/usr/local/ +PREFIX=@prefix@ +INSTALL_DIR=$(DESTDIR)/$(PREFIX) # OTHER_ROOT=/opt/local # For DarwinPorts on OSX # OTHER_ROOT=/sw # Uncomment For Fink on OS X. @@ -53,7 +54,7 @@ FMTS=magproto.o gpx.o geo.o mapsend.o mapsource.o garmin_tables.o \ tef_xml.o maggeo.o pathaway.o vitosmt.o gdb.o bcr.o coto.o \ ignrando.o stmwpp.o msroute.o cst.o nmn4.o mag_pdb.o compegps.o \ yahoo.o unicsv.o wfff_xml.o garmin_txt.o axim_gpb.o gpssim.o \ - wbt-200.o stmsdf.o gtrnctr.o dmtlog.o + wbt-200.o stmsdf.o gtrnctr.o dmtlog.o raymarine.o alan.o FILTERS=position.o radius.o duplicate.o arcdist.o polygon.o smplrout.o \ reverse_route.o sort.o stackfilter.o trackfilter.o discard.o \ @@ -98,17 +99,17 @@ WEB=@DOCDIR@ all: gpsbabel$(EXEEXT) -gpsbabel$(EXEEXT): $(OBJS) @GPSBABEL_DEBUG@ Makefile configure +gpsbabel$(EXEEXT): configure Makefile $(OBJS) @GPSBABEL_DEBUG@ $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) @LIBS@ @EXPAT_LIB@ @USB_LIBS@ $(OUTPUT_SWITCH)$@ gpsbabel-debug: $(OBJS) $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) @LIBS@ @EFENCE_LIB@ @EXPAT_LIB@ @USB_LIBS@ $(OUTPUT_SWITCH)$@ -Makefile: Makefile.in config.status +Makefile gbversion.h: Makefile.in config.status xmldoc/makedoc.in gbversion.h.in CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status -globals.o: - $(CC) @CPPFLAGS@ -c $(GBCFLAGS) -DVERSION=\"$(VERSIOND)\" $< $(OUTPUT_SWITCH)$@ +config.status: configure + $(SHELL) config.status --recheck jeeps/gpslibusb.o: $(CC) @CPPFLAGS@ -c $(GBCFLAGS) @USB_CFLAGS@ @srcdir@/jeeps/gpslibusb.c $(OUTPUT_SWITCH)$@ @@ -122,6 +123,10 @@ clean: configure: configure.in autoconf +tag: + cvs commit + cvs tag gpsbabel_@GBMAJOR@_@GBMINOR@_@GBMICRO@@PACKAGE_RELEASE@ + more-clean: clean tools/mkmoreclean @@ -129,17 +134,31 @@ check: ./testo torture: - ./testo - ./torture_test + @echo "testo in progress... (basic data integrity test)" + @./testo + @echo "vtesto in progress... (valgrind is watching testo)" + @./vtesto + @echo "torture_test in progress... (shortname reduction)" + @./torture_test +# +# Because there are some "non-real" errors like "IGC: bad date" +# test-all does not stop on errors. +# Please inspect the log file (/tmp/gb-test-all.log) for segmentation +# faults, math overflows and other hard errors +# + @echo "test-all in progress... (read/write test between all possible formats)" + @./test-all -s -r reference/expertgps.gpx # # This will only work on UNIX-like substances. # install: @INSTALL_DEBUG@ - install gpsbabel $(DESTDIR)/bin + @mkdir -p $(INSTALL_DIR)/bin + install gpsbabel $(INSTALL_DIR)/bin/ install-debug: - install gpsbabel-debug $(DESTDIR)/bin + @mkdir -p $(INSTALL_DIR)/bin + install gpsbabel-debug $(INSTALL_DIR)/bin/ # Nerdy release stuff that needs to work only on Linux. @@ -155,6 +174,7 @@ dep: echo Edit Makefile.in and bring in /tmp/dep $(WEB)/htmldoc-$(DOCVERSION)/readme.html: FORCE + mkdir -p $(WEB)/htmldoc-$(DOCVERSION) perl xmldoc/makedoc xmlwf xmldoc/readme.xml #check for well-formedness xmllint --noout --valid xmldoc/readme.xml #validate @@ -166,6 +186,32 @@ $(WEB)/htmldoc-$(DOCVERSION)/readme.html: FORCE chmod 755 tools/mkcapabilities tools/mkcapabilities +# +# The .fo and PDF versions depend on additional tools. +# 'fop' must be obtained from http://xmlgraphics.apache.org/fop/ +# 0.92beta seems to work OK, BUT. +# * If you have a package called 'docbook-xml-website' it's reported +# to prevent the build from working. Remove it. (Suse) +# * Sun Java seems to be required. GCJ 1.4.2 doesn't work. You can +# force Sun Java to be used by creating ~/.foprc with 'rpm_mode=' (Fedora) +# Get it from http://www.java.com +# The Hypnenation package must be installed from +# http://offo.sourceforge.net/hyphenation/index.html - be sure to get the +# version that corresponds to the version of FOP that you used above. +# The docbook XSL must be 1.71.1 or higher. +# * Remember to update /etc/xml/catalogs if you manually update this. +# +gpsbabel.fo: FORCE + perl xmldoc/makedoc + xmlwf xmldoc/readme.xml #check for well-formedness + xmllint --noout --valid xmldoc/readme.xml #validate + xsltproc -o $@ xmldoc/babelpdf.xsl xmldoc/readme.xml + +gpsbabel.pdf: gpsbabel.fo + fop -q -fo gpsbabel.fo -pdf gpsbabel.pdf + cp gpsbabel.pdf $(WEB)/htmldoc-$(DOCVERSION)/gpsbabel-$(DOCVERSION).pdf + + gpsbabel.html: FORCE xsltproc \ --stringparam toc.section.depth "1" \ @@ -177,7 +223,7 @@ gpsbabel.html: FORCE readme.txt: gpsbabel.html lynx -nolist -dump gpsbabel.html > $@ -doc: gpsbabel $(WEB)/htmldoc-$(DOCVERSION)/readme.html # readme.txt +doc: gpsbabel $(WEB)/htmldoc-$(DOCVERSION)/readme.html gpsbabel.pdf # readme.txt FORCE: @@ -195,7 +241,7 @@ release-sourcecheck: make clean rm -fr gpsbabel-$(VERSIOND) #rjl make gpsbabel doc gpsbabel.html - @(. tools/functions && ask "Enter 'y' to tag the tree." "y") && cvs tag -F gpsbabel_$(VERSIONU) ; exit 0 + @(. tools/functions && ask "Enter 'y' to tag the tree as gpsbabel_$(VERSIONU)." "y") && cvs tag -F gpsbabel_$(VERSIONU) ; exit 0 cvs export -r gpsbabel_$(VERSIONU) -d gpsbabel-$(VERSIOND) gpsbabel touch gpsbabel-$(VERSIOND)/internal_styles.c @@ -234,6 +280,11 @@ release-rpm: # Do this build in a temporary tree that was a copy of the tagged one # to avoid scribbling in the "real" one. # +# The cross builds are built with mingw. http://mirzam.it.vu.nl/mingw +# and http://mingw.sourceforge.net are convenient sources for that. +# binutils, runtime, w32api, and gcc-core seem to be required. +# + release-winbuild: rm -fr /tmp/gpsbabel-$(VERSIOND)-cross cp -a gpsbabel-$(VERSIOND) /tmp/gpsbabel-$(VERSIOND)-cross @@ -243,7 +294,7 @@ release-winbuild: rm -fr /tmp/gpsbabel-$(VERSIOND)-cross release-upload: /tmp/gpsbabel-$(VERSIOND).tar.gz /tmp/gpsbabel-$(VERSIOND).zip /tmp/dist/SRPMS/gpsbabel-$(VERSIOND)-0.src.rpm /tmp/dist/RPMS/i386/gpsbabel-$(VERSIOND)-0.i386.rpm - @(. tools/functions && ask "Type yes if you want to do the upload now" "yes" ) + @(. tools/functions && ask "Type 'yes' if you want to do the upload now" "yes" ) curl -u anonymous:anonymous --upload-file /tmp/gpsbabel-$(VERSIOND).tar.gz ftp://upload.sf.net/incoming/ curl -u anonymous:anonymous --upload-file /tmp/gpsbabel-$(VERSIOND).zip ftp://upload.sf.net/incoming/ curl -u anonymous:anonymous --upload-file /tmp/dist/SRPMS/gpsbabel-$(VERSIOND)-0.src.rpm ftp://upload.sf.net/incoming/ @@ -251,8 +302,8 @@ release-upload: /tmp/gpsbabel-$(VERSIOND).tar.gz /tmp/gpsbabel-$(VERSIOND).zip release: release-sourcecheck release-tarball release-winbuild release-rpm release-upload -rpm: clean - tools/mkrpm $(VERSD) $(RELEASE) +rpm: + tools/mkrpm $(WEB) $(VERSD) $(RELEASE) mac-release: mkdir -p usr/bin usr/share/gpsbabel/doc @@ -267,6 +318,8 @@ msvc-build: LINK.EXE /NOLOGO @objs.lst ./msvc/expat/libexpat.lib /out:gpsbabel.exe # Machine generated from here down. +alan.o: alan.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h an1.o: an1.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ gbfile.h cet.h cet_util.h inifile.h an1sym.h arcdist.o: arcdist.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ @@ -312,7 +365,11 @@ cst.o: cst.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ gbfile.h cet.h cet_util.h inifile.h strptime.h csv_util.o: csv_util.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h csv_util.h grtcirc.h \ - strptime.h + strptime.h jeeps/gpsmath.h jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h \ + jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \ + jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \ + jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ + jeeps/gpsproj.h delgpl.o: delgpl.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h discard.o: discard.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ @@ -387,7 +444,7 @@ geoniche.o: geoniche.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \ jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h garmin_tables.h globals.o: globals.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ - zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h gbversion.h glogbook.o: glogbook.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h google.o: google.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ @@ -505,7 +562,7 @@ pathaway.o: pathaway.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h coldsync/palm.h \ coldsync/../gbtypes.h coldsync/pdb.h csv_util.h strptime.h pcx.o: pcx.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ - gbfile.h cet.h cet_util.h inifile.h garmin_tables.h + gbfile.h cet.h cet_util.h inifile.h garmin_tables.h csv_util.h polygon.o: polygon.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h filterdefs.h position.o: position.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ @@ -520,6 +577,8 @@ quovadis.o: quovadis.c quovadis.h defs.h config.h queue.h gbtypes.h \ coldsync/palm.h coldsync/../gbtypes.h coldsync/pdb.h radius.o: radius.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h filterdefs.h grtcirc.h +raymarine.o: raymarine.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h csv_util.h reverse_route.o: reverse_route.c defs.h config.h queue.h gbtypes.h \ zlib/zlib.h zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h \ filterdefs.h @@ -611,7 +670,11 @@ wbt-200.o: wbt-200.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ wfff_xml.o: wfff_xml.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h xcsv.o: xcsv.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ - gbfile.h cet.h cet_util.h inifile.h csv_util.h + gbfile.h cet.h cet_util.h inifile.h csv_util.h jeeps/gpsmath.h \ + jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h \ + jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ + jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ + jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h xmlgeneric.o: xmlgeneric.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h xmltag.o: xmltag.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ @@ -780,5 +843,5 @@ zlib/trees.o: zlib/trees.c zlib/deflate.h zlib/zutil.h zlib/zlib.h \ zlib/zconf.h zlib/trees.h zlib/uncompr.o: zlib/uncompr.c zlib/zlib.h zlib/zconf.h zlib/zutil.o: zlib/zutil.c zlib/zutil.h zlib/zlib.h zlib/zconf.h -internal_styles.c: mkstyle.sh style/arc.style style/cambridge.style style/csv.style style/cup.style style/custom.style style/dna.style style/fugawi.style style/garmin301.style style/garmin_poi.style style/geonet.style style/gpsdrive.style style/gpsdrivetrack.style style/gpsman.style style/ktf2.style style/kwf2.style style/mapconverter.style style/mxf.style style/nima.style style/openoffice.style style/s_and_t.style style/saplus.style style/sportsim.style style/tabsep.style style/xmap2006.style style/xmap.style style/xmapwpt.style +internal_styles.c: mkstyle.sh style/arc.style style/cambridge.style style/csv.style style/cup.style style/custom.style style/dna.style style/fugawi.style style/garmin301.style style/garmin_poi.style style/geonet.style style/gpsdrive.style style/gpsdrivetrack.style style/gpsman.style style/kompass_tk.style style/kompass_wp.style style/ktf2.style style/kwf2.style style/mapconverter.style style/mxf.style style/nima.style style/openoffice.style style/s_and_t.style style/saplus.style style/sportsim.style style/tabsep.style style/xmap2006.style style/xmap.style style/xmapwpt.style ./mkstyle.sh > internal_styles.c || (rm -f internal_styles.c ; exit 1) diff --git a/alan.c b/alan.c new file mode 100644 index 000000000..fbc1f7251 --- /dev/null +++ b/alan.c @@ -0,0 +1,938 @@ +/* + + Read/write Alan Map500 Waypoints, Routes and Tracklogs. + + Provides "alanwpr" and "alantrl" formats for gpsbabel. + Currently supports OS 2.xx only. + + Copyright (C) 2007 Gunar Megger, 0xff@quantentunnel.de + Copyright (C) 2005 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include +#include "defs.h" + + +#define MYNAME "alan" + +#define MAXWPT 1000 /* old 500 */ + +#define MAXRTE 50 /* old 20 */ +#define MAXWPTINRTE 150 /* old 30 */ + +#define MAXTRK 8 /* old 5 */ +#define MAXPTINTRK 2500 + +#define WPT_NAME_LEN 8 +#define WPT_COMMENT_LEN 12 + +#define RTE_NAME_LEN 8 +#define RTE_COMMENT_LEN 12 + +#define TRK_NAME_LEN 12 +#define TRK_COMMENT_LEN 13 + +struct wpthdr { + gbuint32 id; + gbint16 num; + gbint16 next; + gbint16 idx[MAXWPT]; + gbuint8 used[MAXWPT]; +}; + +struct wpt { + char name[WPT_NAME_LEN]; + char comment[WPT_COMMENT_LEN]; + struct { + gbint32 x; /* degree * 36000 */ + gbint32 y; /* degree * 36000 */ + } pt; + gbint32 date; + gbint32 time; + gbint16 usecount; + gbint8 checked; + gbint8 reserved; +}; + +struct rtehdr { + gbuint32 id; + gbint16 num; + gbint16 next; + gbint16 idx[MAXRTE]; + gbuint8 used[MAXRTE]; + gbint16 rteno; +}; + +struct rte { + char name[RTE_NAME_LEN]; + char comment[RTE_COMMENT_LEN]; + gbint16 wptnum; + gbint16 wptidx[MAXWPTINRTE]; + gbint16 reserved; + gbint32 date; + gbint32 time; +}; + +struct wprdata { + struct wpthdr wpthdr; + struct wpt wpt[MAXWPT]; + struct rtehdr rtehdr; + struct rte rte[MAXRTE]; +}; + +struct trkhdr { + gbint16 totalpt; + gbint16 next; + char name[TRK_NAME_LEN]; /* 10, null terminated */ + char comment[TRK_COMMENT_LEN]; /* 12, null terminated */ + gbuint8 reserved[3]; + gbuint32 occupied; + gbuint32 show; + gbuint32 fill; +}; + +struct loghdr { + gbuint32 id; + gbint16 num; + gbint16 next; + gbint32 date; + gbint32 time; + struct trkhdr trkhdr[MAXTRK]; +}; + +struct trklog { + struct { + gbint32 x; /* degree * 36000 */ + gbint32 y; /* degree * 36000 */ + } pt[MAXPTINTRK]; + struct { + gbint16 speed; /* km/h * 200 */ + gbint16 height; /* m * 5 */ + } sh[MAXPTINTRK]; +}; + +struct trldata { + struct loghdr loghdr; + struct trklog trklog[MAXTRK]; +}; + +#define WPT_HDR_ID 0x5C38A600 +#define RTE_HDR_ID 0xD87F5900 +#define TRL_HDR_ID 0x38CB1200 + +#define WPT_IDX_NONE -1 /* 0xffff */ +#define WPT_USED 0xff +#define WPT_UNUSED 0 +#define WPT_CHECKED 1 +#define WPT_UNCHECKED 0 + +#define RTE_IDX_NONE -1 /* 0xffff */ +#define RTE_USED 0xff +#define RTE_UNUSED 0 +#define RTE_RTENO_NONE -1 + +#define TRK_USED 1 +#define TRK_UNUSED 0 +#define TRK_SHOW 1 +#define TRK_HIDE 0 +#define TRK_FILL 1 +#define TRK_WRAP 0 + +#define MAP500_PT_SCALE 36000.0 +#define pt2deg(P) ((double)(P) / MAP500_PT_SCALE) +#define deg2pt(D) (gbint32)si_round((double)(D) * MAP500_PT_SCALE) + +#define MAP500_ALTITUDE_SCALE 5.0 +#define hgt2m(A) ((double)(A) / MAP500_ALTITUDE_SCALE) +#define m2hgt(A) (gbint16)si_round((double)(A) * MAP500_ALTITUDE_SCALE) + +#define MAP500_SPEED_SCALE 720.0 +#define sp2mps(S) ((double)(S) / MAP500_SPEED_SCALE) +#define mps2sp(S) (gbint16)si_round((double)(S) * MAP500_SPEED_SCALE) + +#define BYTEORDER_TEST 0x04030201 /* 32bit reference value */ +enum { + SWAP_NONE = 0x1234, /* map500 regular */ + SWAP_BYTES = 0x2143, /* bytes swapped */ + SWAP_WORDS = 0x3412, /* words swapped */ + SWAP_BOTH = 0x4321 /* words + bytes swapped */ +}; + +/**************************************************************************/ + +static gbfile *fin = NULL, *fout = NULL; +struct wprdata WPR; +struct trldata TRL; + +static arglist_t wpr_args[] = { + /* + {"os3", &osversion, "Operating system version 3", + NULL, ARGTYPE_BOOL, ARGNOMINMAX }, + */ + ARG_TERMINATOR +}; +static arglist_t trl_args[] = { + /* + {"os3", &osversion, "Operating system version 3", + NULL, ARGTYPE_BOOL, ARGNOMINMAX }, + */ + ARG_TERMINATOR +}; + +/**************************************************************************/ + +static unsigned int byte_order(void) { + unsigned long test = BYTEORDER_TEST; + unsigned char *ptr; + unsigned int order; + + ptr = (unsigned char *)(&test); + order = (ptr[0] << 12) | (ptr[1] << 8) | (ptr[2] << 4) | ptr[3]; + + return order; +} + +static void sw_bytes(void *word) { + gbuint8 *p = word; + gbuint16 *r = word; + + *r = (gbuint16)(p[1] << 8 | p[0]); +} +static void sw_words(void *dword) { + gbuint16 *p = dword; + gbuint32 *r = dword; + + *r = (gbuint32)(p[0] << 16 | p[1]); +} +static void rev_bytes(void *dword) { + gbuint8 *p = dword; + gbuint32 *r = dword; + + *r = (gbuint32)(p[3] << 24 | p[2] << 16 | p[1] << 8 | p[0]); +} + +static void swap_wpthdr(struct wpthdr *wpthdr, + void (*swap16)(void *), void (*swap32)(void *)) { + int i; + + if ( swap32 != NULL ) { + swap32( &wpthdr->id ); + } + if ( swap16 != NULL ) { + swap16( &wpthdr->num ); + swap16( &wpthdr->next ); + for (i=0; iidx[i] ); + } +} + +static void swap_wpt(struct wpt *wpt, + void (*swap16)(void *), void (*swap32)(void *)) { + if ( swap16 != NULL ) { + swap16( &wpt->usecount ); + } + if ( swap32 != NULL ) { + swap32( &wpt->pt.x ); + swap32( &wpt->pt.y ); + swap32( &wpt->date ); + swap32( &wpt->time ); + } +} + +static void swap_rtehdr(struct rtehdr *rtehdr, + void (*swap16)(void *), void (*swap32)(void *)) { + int i; + + if ( swap16 != NULL) { + swap16( &rtehdr->num ); + swap16( &rtehdr->next ); + for (i=0; iidx[i] ); + swap16( &rtehdr->rteno ); + } + if ( swap32 != NULL ) { + swap32( &rtehdr->id ); + } +} + +static void swap_rte(struct rte *rte, + void (*swap16)(void *), void (*swap32)(void *)) { + int i; + + if (swap16 != NULL) { + swap16( &rte->wptnum ); + for (i=0; iwptidx[i] ); + swap16( &rte->reserved ); + } + if ( swap32 != NULL ) { + swap32( &rte->date ); + swap32( &rte->time ); + } +} + +static void wpr_swap(struct wprdata *wprdata) { + void (*swap16)(void *); + void (*swap32)(void *); + int i; + + switch( byte_order() ) { + case SWAP_NONE: /* same byte oder, LITTLE_ENDIAN */ + return; + break; + case SWAP_BOTH: /* swap words and bytes, BIG_ENDIAN */ + swap16 = sw_bytes; + swap32 = rev_bytes; + break; + case SWAP_WORDS: /* swap words, PDP_ENDIAN */ + swap16 = NULL; + swap32 = sw_words; + break; + case SWAP_BYTES: /* swap bytes */ + swap16 = sw_bytes; + swap32 = NULL; + break; + default: + return; /* never reached */ + } + + swap_wpthdr( &(wprdata->wpthdr), swap16, swap32 ); + for (i=0; i< MAXWPT; i++) + swap_wpt( &(wprdata->wpt[i]), swap16, swap32 ); + swap_rtehdr( &(wprdata->rtehdr), swap16, swap32 ); + for (i=0; irte[i]), swap16, swap32 ); +} + +static void swap_trkhdr(struct trkhdr *trkhdr, + void (*swap16)(void *), void (*swap32)(void *)) { + if ( swap16 != NULL ) { + swap16( &(trkhdr->totalpt) ); + swap16( &(trkhdr->next) ); + } + if ( swap32 != NULL ) { + swap32( &(trkhdr->occupied) ); + swap32( &(trkhdr->show) ); + swap32( &(trkhdr->fill) ); + } +} + +static void swap_loghdr(struct loghdr *loghdr, + void (*swap16)(void *), void (*swap32)(void *)) { + int i; + + if ( swap16 != NULL ) { + swap16( &(loghdr->num) ); + swap16( &(loghdr->next) ); + } + if ( swap32 != NULL ) { + swap32( &(loghdr->id) ); + swap32( &(loghdr->date) ); + swap32( &(loghdr->time) ); + } + for (i=0; itrkhdr[i]), swap16, swap32 ); +} + +static void swap_trklog(struct trklog *trklog, + void (*swap16)(void *), void (*swap32)(void *)) { + int i; + + if ( swap16 != NULL ) { + for (i=0; ish[i].speed) ); + swap16( &(trklog->sh[i].height) ); + } + } + if ( swap32 != NULL ) { + for (i=0; ipt[i].x) ); + swap32( &(trklog->pt[i].y) ); + } + } +} + +static void trl_swap(struct trldata *trldata) { + void (*swap16)(void *); + void (*swap32)(void *); + int i; + + switch( byte_order() ) { + case SWAP_NONE: /* same byte oder, LITTLE_ENDIAN */ + return; + break; + case SWAP_BOTH: /* swap words and bytes, BIG_ENDIAN */ + swap16 = sw_bytes; + swap32 = rev_bytes; + break; + case SWAP_WORDS: /* swap words, PDP_ENDIAN */ + swap16 = NULL; + swap32 = sw_words; + break; + case SWAP_BYTES: /* swap bytes */ + swap16 = sw_bytes; + swap32 = NULL; + break; + default: + return; /* never reached */ + } + + swap_loghdr( &(trldata->loghdr), swap16, swap32); + for (i=0; itrklog[i]), swap16, swap32); +} + + +/**************************************************************************/ + +static void str2lab(char *dest, char *src, int len, char *fmt, int n) { + int i,j; + + j = 0; + if (src != NULL) { + for (i=0; itm_mday | ((tm->tm_mon+1)<<8) | ((tm->tm_year+1900)<<16); + *time = t % 86400; +} + +static time_t unpack_time(gbint32 date, gbint32 time) { + time_t result; + short year, month, day; + static int m_to_d[12] = + {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; + + year = (date >> 16) & 0xffff; + month = (date >> 8) & 0xff; /* 1-12 */ + day = date & 0xff; /* 1-31 */ + + month -= 1; /* fit struct tm */ + year += month / 12; + + if (month < 0) { + year -= 1; + month += 12; + } + result = (year - 1970) * 365 + m_to_d[month]; + if (month <= 1) + year -= 1; + result += (year - 1968) / 4; + result -= (year - 1900) / 100; + result += (year - 1600) / 400; + result += day; + result -= 1; + result *= 86400; + result += time; /* map500 time is inseconds of the day */ + + return result; +} + +/**************************************************************************/ + +static waypoint * get_wpt(struct wprdata *wprdata, unsigned n) { + struct wpthdr *wpthdr; + struct wpt *wpt; + int j, idx; + waypoint *WP; + + wpthdr = &(wprdata->wpthdr); + idx = wpthdr->idx[n]; + + if (idx == WPT_IDX_NONE || wpthdr->used[idx] == WPT_UNUSED) + return NULL; + wpt = &(wprdata->wpt[idx]); + + WP = waypt_new(); + WP->latitude = -pt2deg(wpt->pt.y); + WP->longitude = pt2deg(wpt->pt.x); + WP->creation_time = unpack_time(wpt->date, wpt->time); + for(j=WPT_NAME_LEN-1; j >= 0 && wpt->name[j] == ' '; j--) {}; + WP->shortname = xstrndup(wpt->name,j+1); + for(j=WPT_COMMENT_LEN-1; j >= 0 && wpt->comment[j] == ' '; j--) {}; + if (j >= 0) + WP->description = xstrndup(wpt->comment, j+1); + else + WP->description = xstrdup(""); + WP->notes = xstrdup(""); + + return WP; +} + +static void wpr_read(void) { + struct wprdata wprdata; + struct rtehdr *rtehdr; + struct rte *rte; + int i, j, idx; + waypoint *WP; + route_head *RT; + + if ( gbfread(&wprdata, sizeof(struct wprdata), 1, fin) != 1 ) + fatal(MYNAME ": Read error on %s\n", fin->name); + wpr_swap(&wprdata); + if ( wprdata.wpthdr.id != WPT_HDR_ID || + wprdata.rtehdr.id != RTE_HDR_ID ) + fatal(MYNAME ": %s is not in Alan .wpr format.\n", fin->name); + + /* waypoints */ + for (i=0; iidx[i]; + if (idx == RTE_IDX_NONE || rtehdr->used[idx] == RTE_UNUSED) + continue; + rte = &(wprdata.rte[idx]); + + RT = route_head_alloc(); + RT->rte_num = i; + for(j=RTE_NAME_LEN-1; j >= 0 && rte->name[j] == ' '; j--) {}; + RT->rte_name = xstrndup(rte->name,j+1); + for(j=RTE_COMMENT_LEN-1; j >= 0 && rte->comment[j] == ' '; j--) {}; + if (j >= 0) + RT->rte_desc = xstrndup(rte->comment,j+1); + else + RT->rte_desc = xstrdup(""); + + route_add_head(RT); + + /* route points */ + for(j=0; jwptnum; j++) { + WP = get_wpt(&wprdata, rte->wptidx[j]); + if ( WP != NULL ) + route_add_wpt(RT, WP); + } + } +} + +static void trl_read(void) { + struct trldata trldata; + struct trkhdr *trkhdr; + struct trklog *trklog; + waypoint *WP; + route_head *TL; + int i, j; + + for (i=0; iname); + } + gbfseek(fin, 0x10000 * MAXTRK/2, SEEK_SET); + if ( gbfread( &(trldata.loghdr), sizeof(struct loghdr), 1, fin) != 1) + fatal(MYNAME ": Read error on %s\n", fin->name); + trl_swap(&trldata); + if ( trldata.loghdr.id != TRL_HDR_ID ) + fatal(MYNAME ": %s is not in Alan .trl format.\n", fin->name); + + for(i=0; ioccupied == TRK_UNUSED) + continue; + TL = route_head_alloc(); + for(j=TRK_NAME_LEN-1; + j >= 0 && (trkhdr->name[j] == ' ' || trkhdr->name[j] == '\0'); + j--) {}; + TL->rte_name = xstrndup(trkhdr->name,j+1); + for(j=TRK_COMMENT_LEN-1; + j >= 0 && (trkhdr->comment[j] == ' ' || trkhdr->comment[j] == '\0'); + j--) {}; + TL->rte_desc = xstrndup(trkhdr->comment,j+1); + TL->rte_num = i; + + track_add_head(TL); + + /* track points */ + trklog = &(trldata.trklog[i]); + for(j=0; jtotalpt; j++) { + WP = waypt_new(); + WP->latitude = -pt2deg(trklog->pt[j].y); + WP->longitude = pt2deg(trklog->pt[j].x); + WP->altitude = hgt2m(trklog->sh[j].height); + if ( trklog->sh[j].speed >= 0 ) + WP->speed = sp2mps(trklog->sh[j].speed); + else /* bad speed < 0 - set to 0.0 */ + WP->speed = unknown_speed; + track_add_wpt(TL, WP); + } + } +} + +/**************************************************************************/ + +static int find_wpt(struct wprdata *wprdata, const waypoint *WP) { + struct wpt pattern, *wpt; + int i, wpt_idx; + + str2lab(pattern.name, WP->shortname, WPT_NAME_LEN, NULL, 0); + pattern.pt.x = deg2pt(WP->longitude); + pattern.pt.y = deg2pt(-WP->latitude); + + wpt = wprdata->wpt; + for (i=0; iwpthdr.idx[i]; + if ( wpt_idx == WPT_IDX_NONE || + wprdata->wpthdr.used[wpt_idx] == WPT_UNUSED ) + continue; + if ( strncmp( wpt[wpt_idx].name, pattern.name, WPT_NAME_LEN) == 0 && + wpt[wpt_idx].pt.x == pattern.pt.x && + wpt[wpt_idx].pt.y == pattern.pt.y ) + return i; + } + + return -1; +} + +static int add_wpt(struct wprdata *wprdata, const waypoint *WP,int isroute) { + struct wpthdr *wpthdr; + int hdr_idx, wpt_idx; + struct wpt *wpt; + int i; + + wpthdr = &(wprdata->wpthdr); + + hdr_idx = find_wpt(wprdata, WP); + if ( hdr_idx >= 0 ) { + /* duplicate waypoint */ + if (isroute) { + wpt = &(wprdata->wpt[wpthdr->idx[hdr_idx]]); + wpt->usecount ++; + } + /* + warning(MYNAME ": using duplicate waypoint '%s' at (%f°, %f°)\n", + WP->shortname, WP->latitude, WP->longitude); + */ + return hdr_idx; + } + + for (i=0; iidx[i] != WPT_IDX_NONE; i++) { } + hdr_idx = i; + for (i=0; iused[i] != WPT_UNUSED; i++) { } + wpt_idx = i; + if (wpthdr->num >= MAXWPT || hdr_idx >= MAXWPT || wpt_idx >= MAXWPT ) + fatal(MYNAME ": Can't store more than %u waypoints\n", MAXWPT); + + wpt = &(wprdata->wpt[wpt_idx]); + str2lab(wpt->name, WP->shortname, WPT_NAME_LEN, "W%05d", wpt_idx); + str2lab(wpt->comment, WP->description, WPT_COMMENT_LEN, NULL, 0); + wpt->pt.x = deg2pt(WP->longitude); + wpt->pt.y = deg2pt(-WP->latitude); + wpt->usecount = isroute ? 1 : 0; + wpt->checked = isroute ? 0 : 1; + wpt->reserved = 0; + pack_time(WP->creation_time, &(wpt->date), &(wpt->time)); + + wpthdr->idx[hdr_idx] = wpt_idx; + wpthdr->used[wpt_idx] = WPT_USED; + wpthdr->num++; + wpthdr->next++; + if (wpthdr->next >= MAXWPT) /* overrun */ + wpthdr->next = 0; + + return hdr_idx; +} + +static void wpr_waypoint(const waypoint *WP) { + add_wpt(&WPR, WP, 0); +} + +static void wpr_route_hdr(const route_head *RT) { + struct rtehdr *rtehdr; + int hdr_idx, rte_idx; + struct rte *rte; + int i; + + rtehdr = &(WPR.rtehdr); + for (i=0; iidx[i] != RTE_IDX_NONE; i++) { } + hdr_idx = i; + for (i=0; iused[i] != RTE_UNUSED; i++) { } + rte_idx = i; + if (rtehdr->num >= MAXRTE || hdr_idx >= MAXRTE || rte_idx >= MAXRTE ) + fatal(MYNAME ": Can't store more than %u routes", MAXRTE); + + rte = &(WPR.rte[rte_idx]); + str2lab(rte->name, RT->rte_name, RTE_NAME_LEN, "R%03d", rte_idx); + str2lab(rte->comment, RT->rte_desc, RTE_COMMENT_LEN, NULL, 0); + pack_time(time(NULL), &(rte->date), &(rte->time)); + + rtehdr->idx[hdr_idx] = rte_idx; + rtehdr->used[rte_idx] = RTE_USED; + rtehdr->num++; + rtehdr->next++; + if (rtehdr->next >= MAXRTE) /* overrun */ + rtehdr->next = 0; + + /* if you want the new route to be active, uncomment the next line */ + /* rtehdr->rteno = rte_idx; */ +} + +static void wpr_route_wpt(const waypoint *WP) { + struct rte *rte; + int wpt_idx; + + rte = &(WPR.rte[WPR.rtehdr.num -1]); + if ( rte->wptnum >= MAXWPTINRTE ) + fatal(MYNAME ": Can't store more than %u waypoints per route", MAXWPTINRTE); + + wpt_idx = add_wpt(&WPR, WP, 1); + + rte->wptidx[rte->wptnum] = wpt_idx; + rte->wptnum ++; +} + +static void wpr_route_trl(const route_head *RT) { + /* should we do some final sanity checks? */ +} + +static void wpr_write(void) { + int i; + + WPR.wpthdr.id = WPT_HDR_ID; + WPR.wpthdr.num = WPR.wpthdr.next = 0; + for (i=0; iname); +} + +/**************************************************************************/ + +static void trl_track_hdr(const route_head *TL) { + struct trkhdr *trkhdr; + int idx, l; + + trkhdr = TRL.loghdr.trkhdr; + + for (idx=0; idx< MAXTRK && trkhdr[idx].occupied != TRK_UNUSED; idx++) {}; + if (idx >= MAXTRK) + fatal(MYNAME ": Can't store more than %u tracklogs", MAXTRK); + + if ( TL->rte_name != NULL ) + strncpy(trkhdr[idx].name, TL->rte_name, TRK_NAME_LEN); + if ( *(trkhdr[idx].name) == '\0' ) + sprintf(trkhdr[idx].name, "T%03d", idx); + trkhdr[idx].name[TRK_NAME_LEN-1] = '\0'; + + if ( TL->rte_desc != NULL ) { + strncpy(trkhdr[idx].comment, TL->rte_desc, TRK_COMMENT_LEN); + l = strlen(TL->rte_desc); + if ( l < TRK_COMMENT_LEN-1 ) + memset(trkhdr[idx].comment + l, ' ', TRK_COMMENT_LEN - l); + } + trkhdr[idx].comment[TRK_COMMENT_LEN-1] = '\0'; + + trkhdr[idx].comment[TRK_COMMENT_LEN-1] = '\0'; + trkhdr[idx].occupied = TRK_USED; + trkhdr[idx].totalpt = 0; + trkhdr[idx].next = 0; + + TRL.loghdr.num = idx; +} + +static void trl_track_wpt(const waypoint *WP) { + struct trklog *trklog; + struct trkhdr *trkhdr; + int trk_idx, log_idx; + + trk_idx = TRL.loghdr.num; + + trkhdr = &(TRL.loghdr.trkhdr[trk_idx]); + if ( trkhdr->totalpt >= MAXPTINTRK ) + fatal(MYNAME ": Can't store more than %u points per track", MAXPTINTRK); + log_idx = trkhdr->next; + + trklog = &(TRL.trklog[trk_idx]); + trklog->pt[log_idx].x = deg2pt( WP->longitude); + trklog->pt[log_idx].y = deg2pt(-WP->latitude); + if ( WP->speed != unknown_speed ) + trklog->sh[log_idx].speed = mps2sp(WP->speed); + if ( WP->altitude != unknown_alt ) + trklog->sh[log_idx].height = m2hgt(WP->altitude); + + trkhdr->totalpt ++; + trkhdr->next = trkhdr->totalpt; +} + +static void trl_track_tlr(const route_head *TL) { + struct trkhdr *trkhdr; + int trk_idx; + + trk_idx = TRL.loghdr.num; + trkhdr = &(TRL.loghdr.trkhdr[trk_idx]); + + if ( trkhdr->totalpt == 0 ) + trkhdr->occupied = TRK_UNUSED; + + TRL.loghdr.num = -1; +} + +static void trl_write(void) { + struct trkhdr *trkhdr; + void *buf; + int i; + size_t fill; + + TRL.loghdr.id = TRL_HDR_ID; + TRL.loghdr.num = TRL.loghdr.next = -1; + TRL.loghdr.date = TRL.loghdr.time = 0; + for (i=0; itotalpt = 0; + trkhdr->next = 0; + memset(trkhdr->name, 0, TRK_NAME_LEN); + memset(trkhdr->comment, ' ', TRK_COMMENT_LEN); + trkhdr->comment[TRK_COMMENT_LEN-1] = '\0'; + trkhdr->occupied = TRK_UNUSED; + trkhdr->show = TRK_HIDE; + trkhdr->fill = TRK_FILL; + } + memset(TRL.trklog, 0xff, sizeof(struct trklog) * MAXTRK); + + track_disp_all(trl_track_hdr, trl_track_tlr, trl_track_wpt); + + trl_swap(&TRL); + + fill = 0x10000 - 2 * sizeof(struct trklog); + buf = xmalloc(fill); + if (buf == NULL) + fatal(MYNAME ": Not enough memory\n"); + memset(buf, 0xff, fill); + + for (i=0; iname); + } + xfree(buf); + + fill = 0x1000 - sizeof(struct loghdr); + buf = xmalloc(fill); + if (buf == NULL) + fatal(MYNAME ": Not enough memory\n"); + memset(buf, 0xff, fill); + + if ( gbfwrite(&(TRL.loghdr), sizeof(struct loghdr), 1, fout) != 1 || + gbfwrite(buf, fill, 1, fout) != 1 ) + fatal(MYNAME ": Write error on %s\n", fout->name); + xfree(buf); +} + +/**************************************************************************/ + +static void alan_rd_init(const char *fname) { + fin = gbfopen(fname, "r", MYNAME); +} + +static void alan_rd_deinit(void) { + gbfclose(fin); + fin = NULL; +} + + +static void alan_wr_init(const char *fname) { + fout = gbfopen(fname, "w", MYNAME); +} + +static void alan_wr_deinit(void) { + gbfclose(fout); + fout = NULL; +} + + +static void alan_exit(void) { + return; +} + +/**************************************************************************/ + +ff_vecs_t alanwpr_vecs = { + ff_type_file, + { + ff_cap_read | ff_cap_write /* waypoints */, + ff_cap_none /* tracks */, + ff_cap_read | ff_cap_write /* routes */ + }, + alan_rd_init, + alan_wr_init, + alan_rd_deinit, + alan_wr_deinit, + wpr_read, + wpr_write, + alan_exit, + wpr_args, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command + line parameter */ +}; + +ff_vecs_t alantrl_vecs = { + ff_type_file, + { + ff_cap_none /* waypoints */, + ff_cap_read | ff_cap_write /* tracks */, + ff_cap_none /* routes */ + }, + alan_rd_init, + alan_wr_init, + alan_rd_deinit, + alan_wr_deinit, + trl_read, + trl_write, + alan_exit, + trl_args, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command + line parameter */ +}; diff --git a/an1.c b/an1.c index c6483eb61..684579598 100644 --- a/an1.c +++ b/an1.c @@ -1266,7 +1266,11 @@ my_write( void ) ff_vecs_t an1_vecs = { ff_type_file, - FF_CAP_RW_ALL, + { + ff_cap_read | ff_cap_write /* waypoints */, + ff_cap_write /* tracks */, + ff_cap_read | ff_cap_write /* routes */, + }, rd_init, wr_init, rd_deinit, diff --git a/axim_gpb.c b/axim_gpb.c index 398fe3788..d7e70da6f 100644 --- a/axim_gpb.c +++ b/axim_gpb.c @@ -29,7 +29,7 @@ #define RECORD_LEN 344 -static FILE *fin; +static gbfile *fin; static arglist_t axim_gpb_args[] = { @@ -124,13 +124,13 @@ decode_buff(const char *buff, route_head *track) static void axim_gpb_rd_init(const char *fname) { - fin = xfopen(fname, "rb", MYNAME); + fin = gbfopen(fname, "rb", MYNAME); } static void axim_gpb_rd_deinit(void) { - fclose(fin); + gbfclose(fin); } static void @@ -139,18 +139,10 @@ axim_gpb_read(void) char buff[RECORD_LEN]; route_head *track = NULL; size_t bytes; - long filesize, left; - fseek(fin, 0, SEEK_END); - filesize = ftell(fin); - - left = filesize - ((filesize / RECORD_LEN) * RECORD_LEN); - is_fatal((left != 0), MYNAME ": Invalid or unsupported file (filesize)."); - - fseek(fin, 0, SEEK_SET); /* seek file to start */ - - while ((bytes = fread(buff, 1, RECORD_LEN, fin))) + while ((bytes = gbfread(buff, 1, RECORD_LEN, fin))) { + is_fatal((bytes != RECORD_LEN), MYNAME ": Invalid or unsupported file (filesize)."); if (track == NULL) { track = route_head_alloc(); diff --git a/bcr.c b/bcr.c index 657d21733..d212f3e3d 100644 --- a/bcr.c +++ b/bcr.c @@ -2,7 +2,7 @@ Support for Motorrad Routenplaner (Map&Guide) .bcr files. - Copyright (C) 2005-2006 Olaf Klein, o.b.klein@gpsbabel.org + Copyright (C) 2005-2007 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,6 +21,8 @@ /* 2006/01/22: reader simplified with inifile library + 2007/01/30: new option prefer_shortnames + don't check global_opts.objective */ #include "defs.h" @@ -43,7 +45,7 @@ but this seems to be used by Map&Guide when exporting to XML. */ -static FILE *fout; +static gbfile *fout; static char *filename; static int curr_rte_num, target_rte_num; static double radius; @@ -54,12 +56,18 @@ static inifile_t *ini; static char *rtenum_opt; static char *rtename_opt; static char *radius_opt; +static char *prefer_shortnames_opt; static arglist_t bcr_args[] = { - {"index", &rtenum_opt, "Index of route to write (if more the one in source)", NULL, ARGTYPE_INT, "1", NULL }, - {"name", &rtename_opt, "New name for the route", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - {"radius", &radius_opt, "Radius of our big earth (default 6371000 meters)", "6371000", ARGTYPE_FLOAT, ARG_NOMINMAX }, + {"index", &rtenum_opt, "Index of route to write (if more the one in source)", + NULL, ARGTYPE_INT, "1", NULL }, + {"name", &rtename_opt, "New name for the route", + NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + {"radius", &radius_opt, "Radius of our big earth (default 6371000 meters)", "6371000", + ARGTYPE_FLOAT, ARG_NOMINMAX }, + {"prefer_shortnames", &prefer_shortnames_opt, "Use shortname instead of description", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, ARG_TERMINATOR }; @@ -104,8 +112,8 @@ bcr_create_waypts_from_route(route_head *route) QUEUE_FOR_EACH(&route->waypoint_list, elem, tmp) { - wpt = waypt_dupe((waypoint *) elem); - waypt_add(wpt); + wpt = waypt_dupe((waypoint *) elem); + waypt_add(wpt); } } @@ -204,14 +212,14 @@ static void bcr_wr_init(const char *fname) { filename = xstrdup(fname); - fout = xfopen(fname, "wb", MYNAME); + fout = gbfopen(fname, "wb", MYNAME); bcr_init_radius(); } static void bcr_wr_deinit(void) { - fclose(fout); + gbfclose(fout); xfree(filename); } @@ -225,22 +233,22 @@ bcr_write_wpt(const waypoint *wpt) { } -void bcr_write_line(FILE *fout, const char *key, int *index, const char *value) +void bcr_write_line(gbfile *fout, const char *key, int *index, const char *value) { if (value == NULL) /* this is mostly used in the world of windows */ { /* so we respectfully add a CR/LF on each line */ - fprintf(fout, "%s\r\n", key); + gbfprintf(fout, "%s\r\n", key); } else { - char *tmp; - - tmp = (value != NULL) ? xstrdup(value) : xstrdup(""); - if (index != NULL) - fprintf(fout, "%s%d=%s\r\n", key, *index, tmp); - else - fprintf(fout, "%s=%s\r\n", key, tmp); - xfree(tmp); + char *tmp; + + tmp = (value != NULL) ? xstrdup(value) : xstrdup(""); + if (index != NULL) + gbfprintf(fout, "%s%d=%s\r\n", key, *index, tmp); + else + gbfprintf(fout, "%s=%s\r\n", key, tmp); + xfree(tmp); } } @@ -257,34 +265,33 @@ bcr_route_header(const route_head *route) if (curr_rte_num != target_rte_num) return; bcr_write_line(fout, "[CLIENT]", NULL, NULL); /* client section */ - bcr_write_line(fout, "REQUEST", NULL, "TRUE"); c = route->rte_name; if (rtename_opt != 0) c = rtename_opt; if (c != NULL) - bcr_write_line(fout, "ROUTENAME", NULL, c); + bcr_write_line(fout, "ROUTENAME", NULL, c); else - bcr_write_line(fout, "ROUTENAME", NULL, "Route"); + bcr_write_line(fout, "ROUTENAME", NULL, "Route"); bcr_write_line(fout, "DESCRIPTIONLINES", NULL, "1"); bcr_write_line(fout, "DESCRIPTION1", NULL, ""); i = 0; + QUEUE_FOR_EACH(&route->waypoint_list, elem, tmp) { - i++; - wpt = (waypoint *) elem; - - strncpy(symbol, "Standort", sizeof(symbol)); - if (wpt->icon_descr != 0) - { - icon = gt_find_icon_number_from_desc(wpt->icon_descr, MAPSOURCE); - if ((icon >= 69) && (icon <= 72)) - strncpy(symbol, "Town", sizeof(symbol)); - } - snprintf(buff, sizeof(buff), "%s,%s", symbol, "999999999"); - bcr_write_line(fout, "STATION", &i, buff); + i++; + wpt = (waypoint *) elem; + + strncpy(symbol, "Standort", sizeof(symbol)); + if (wpt->icon_descr != 0) { + icon = gt_find_icon_number_from_desc(wpt->icon_descr, MAPSOURCE); + if ((icon >= 69) && (icon <= 72)) + strncpy(symbol, "Town", sizeof(symbol)); + } + snprintf(buff, sizeof(buff), "%s,%s", symbol, "999999999"); + bcr_write_line(fout, "STATION", &i, buff); } bcr_write_line(fout, "[COORDINATES]", NULL, NULL); /* coords section */ @@ -295,18 +302,18 @@ bcr_route_header(const route_head *route) i = 0; QUEUE_FOR_EACH(&route->waypoint_list, elem, tmp) { - i++; - wpt = (waypoint *) elem; - - bcr_wgs84_to_mercator(wpt->latitude, wpt->longitude, &north, &east); - - if (north > nmax) nmax = north; - if (east > emax) emax = east; - if (north < nmin) nmin = north; - if (east < emin) emin = east; - - snprintf(buff, sizeof(buff), "%d,%d", east, north); - bcr_write_line(fout, "STATION", &i, buff); + i++; + wpt = (waypoint *) elem; + + bcr_wgs84_to_mercator(wpt->latitude, wpt->longitude, &north, &east); + + if (north > nmax) nmax = north; + if (east > emax) emax = east; + if (north < nmin) nmin = north; + if (east < emin) emin = east; + + snprintf(buff, sizeof(buff), "%d,%d", east, north); + bcr_write_line(fout, "STATION", &i, buff); } bcr_write_line(fout, "[DESCRIPTION]", NULL, NULL); /* descr. section */ @@ -314,11 +321,12 @@ bcr_route_header(const route_head *route) i = 0; QUEUE_FOR_EACH(&route->waypoint_list, elem, tmp) { - i++; - wpt = (waypoint *) elem; - c = wpt->description; - if (c == NULL) c = wpt->shortname; - bcr_write_line(fout, "STATION", &i, c); + i++; + wpt = (waypoint *) elem; + c = wpt->description; + if (prefer_shortnames_opt || (c == NULL) || (*c == '\0')) + c = wpt->shortname; + bcr_write_line(fout, "STATION", &i, c); } bcr_write_line(fout, "[ROUTE]", NULL, NULL); /* route section */ @@ -331,21 +339,16 @@ bcr_route_header(const route_head *route) static void bcr_data_write(void) { - - if (global_opts.objective == rtedata) - { - target_rte_num = 1; - - if (rtenum_opt != NULL) - { + target_rte_num = 1; + + if (rtenum_opt != NULL) { target_rte_num = atoi(rtenum_opt); if (((unsigned)target_rte_num > route_count()) || (target_rte_num < 1)) - fatal(MYNAME ": invalid route number %d (1..%d))!\n", - target_rte_num, route_count()); - } - curr_rte_num = 0; - route_disp_all(bcr_route_header, bcr_route_trailer, bcr_write_wpt); + fatal(MYNAME ": invalid route number %d (1..%d))!\n", + target_rte_num, route_count()); } + curr_rte_num = 0; + route_disp_all(bcr_route_header, bcr_route_trailer, bcr_write_wpt); } ff_vecs_t bcr_vecs = { diff --git a/cet.c b/cet.c index abc8b64b6..99a99a4f2 100644 --- a/cet.c +++ b/cet.c @@ -305,6 +305,7 @@ cet_str_any_to_utf8(const char *src, const cet_cs_vec_t *vec) cin = (char *)src; if (cin == NULL) return NULL; + if (vec->ucs4_count == 0) return xstrdup(src); /* UTF-8 -> UTF-8 */ len = 0; while (*cin != '\0') /* determine length of resulting UTF-8 string */ diff --git a/coastexp.c b/coastexp.c index 3af5b093d..691661275 100644 --- a/coastexp.c +++ b/coastexp.c @@ -1,5 +1,6 @@ /* Copyright (C) 2004 Justin Broughton, justinbr@earthlink.net + Copyright (C) 2007 Robert Lipe, robertlipe@gpsbabel.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,8 +30,7 @@ #include "uuid.h" -static FILE *fd; -static FILE *ofd; +static gbfile *fd, *ofd; #define MYNAME "coastexp" #define MY_CBUF 4096 @@ -96,7 +96,9 @@ ce_add_mark_to_route(ce_route *route, ce_mark *mark) static void ce_free_mark(ce_mark *mark) { - xfree(mark->id); + dequeue(&mark->Q); + if (mark->id) + xfree(mark->id); if (mark->created) xfree(mark->created); xfree(mark); @@ -116,6 +118,16 @@ ce_free_route(ce_route *route) // Don't free the waypoint since this is done elsewhere } +/* Allocate a mark */ +static ce_mark * +ce_alloc_mark(const waypoint *wpt, const char *id) +{ + ce_mark *res = xcalloc(sizeof(ce_mark), 1); + res->id = (char *) id; + res->wp = (waypoint *) wpt; + return res; +} + #if !HAVE_LIBEXPAT void ce_rd_init(const char *fname) @@ -146,18 +158,14 @@ ce_start(void *data, const XML_Char *xml_el, const XML_Char **xml_attr) // Create a CE route object and add it to the list of routes currentRoute = (ce_route *) xcalloc(sizeof (ce_route), 1); currentRoute->id=xstrdup(ap[1]); - if (doing_rtes) - currentRoute->r = route_head_alloc(); + currentRoute->r = route_head_alloc(); QUEUE_INIT(¤tRoute->ce_mark_head); - if (doing_rtes) - ce_add_route(currentRoute); + ce_add_route(currentRoute); } } } else if (0 == strcmp(el, "Mark")) { inMark = 1; - currentMark = (ce_mark *) xcalloc(sizeof (ce_mark), 1); - currentMark->wp = NULL; - currentMark->used = 0; + currentMark = ce_alloc_mark(NULL, NULL); ce_add_mark(currentMark); for (ap = attr; *ap; ap+=2) { if (0 == strcmp(ap[0], "id")) { @@ -179,9 +187,7 @@ ce_end(void *data, const XML_Char *xml_el) { const char *el = xml_convert_to_char_string(xml_el); if (0 == strcmp(el, "Route")) { - if (!doing_rtes) - ce_free_route(currentRoute); - inRoute = 0; + inRoute = 0; /* ??? */ } else if (0 == strcmp(el, "Mark")) inMark = 0; @@ -215,10 +221,7 @@ ce_cdata(void *dta, const XML_Char *xml_s, int len) if (inRoute) { // We are processing the marks in a route so create a CE mark object // and add it to the current route - ce_mark *mark = (ce_mark *) xcalloc(sizeof (ce_mark), 1); - mark->id = xstrdup(s); - mark->created = NULL; - mark->wp = NULL; + ce_mark *mark = (ce_mark *) ce_alloc_mark(NULL, xstrdup(s)); ce_add_mark_to_route(currentRoute, mark); } } else if (0 == strcmp(element, "Position")) { @@ -285,7 +288,6 @@ ce_cdata(void *dta, const XML_Char *xml_s, int len) } } else if (inRoute) { - if (doing_rtes) currentRoute->r->rte_name = xstrdup(s); } } else if (0 == strcmp(element, "Description")) { @@ -312,7 +314,7 @@ ce_cdata(void *dta, const XML_Char *xml_s, int len) void ce_rd_init(const char *fname) { - fd = xfopen(fname, "r", MYNAME); + fd = gbfopen(fname, "r", MYNAME); QUEUE_INIT(&ce_route_head); QUEUE_INIT(&ce_mark_head); @@ -333,10 +335,11 @@ void ce_read(void) { int len; - char buf[MY_CBUF]; + char buf[MY_CBUF + 1]; - while ((len = fread(buf, 1, sizeof(buf), fd))) { - if (!XML_Parse(psr, buf, len, feof(fd))) { + while ((len = gbfread(buf, 1, sizeof(buf) - 1, fd))) { + buf[len] = '\0'; + if (!XML_Parse(psr, buf, len, gbfeof(fd))) { fatal(MYNAME ":Parse error at %d: %s\n", (int) XML_GetCurrentLineNumber(psr), XML_ErrorString(XML_GetErrorCode(psr))); @@ -397,7 +400,6 @@ ce_remove_used_marks(void) ce_mark *mark = (ce_mark *) elem; if (mark->used) { - dequeue(elem); if (mark->wp) waypt_free(mark->wp); ce_free_mark(mark); @@ -444,11 +446,9 @@ ce_rd_deinit(void) */ queue *elem, *tmp; - if (doing_rtes) { - ce_fix_route_mark_waypoints(); + ce_fix_route_mark_waypoints(); ce_check_route_names(); - ce_remove_used_marks(); - } + ce_remove_used_marks(); // Log results if (global_opts.debug_level > 1) @@ -457,7 +457,6 @@ ce_rd_deinit(void) // Add routes to GPSBabel QUEUE_FOR_EACH(&ce_route_head, elem, tmp) { ce_route *route = (ce_route *) elem; - if (doing_rtes) { queue *elem2, *tmp2; route_add_head(route->r); QUEUE_FOR_EACH(&route->ce_mark_head, elem2, tmp2) { @@ -467,7 +466,6 @@ ce_rd_deinit(void) else printf("Undefined mark: %s\n", mark->id); } - } ce_free_route(route); } @@ -478,7 +476,7 @@ ce_rd_deinit(void) ce_free_mark(mark); } - fclose(fd); + gbfclose(fd); xfree(element); xfree(cdatastr); } @@ -494,13 +492,14 @@ ce_wr_init(const char *fname) uuid_buffer = xcalloc(MY_UBUF,1); xml_buffer = xcalloc(MY_XBUF, 1); - ofd = xfopen(fname, "w", MYNAME); + ofd = gbfopen(fname, "w", MYNAME); + srand(gpsbabel_now); } void ce_wr_deinit(void) { - fclose(ofd); + gbfclose(ofd); // Free the buffers used for writing xfree(time_buffer); @@ -512,7 +511,7 @@ ce_wr_deinit(void) static char * ce_gen_creation_time(time_t tm) { - xml_fill_in_time(time_buffer, tm, XML_SHORT_TIME); + xml_fill_in_time(time_buffer, tm, 0, XML_SHORT_TIME); return time_buffer; } @@ -541,11 +540,9 @@ ce_gen_uuid(void) static void ce_route_hdr(const route_head *rte) { - if (doing_rtes) { - sprintf(xml_buffer, "{%s}", ce_gen_uuid()); - write_xml_entity_begin2(ofd, "\t", "Route", "created", ce_gen_current_time(), "id", xml_buffer); - write_xml_entity_begin0(ofd, "\t\t", "Marks"); - } + sprintf(xml_buffer, "{%s}", ce_gen_uuid()); + write_xml_entity_begin2(ofd, "\t", "Route", "created", ce_gen_current_time(), "id", xml_buffer); + write_xml_entity_begin0(ofd, "\t\t", "Marks"); } /* Generate route body XML */ @@ -554,23 +551,21 @@ ce_route_disp(const waypoint *waypointp) { char *uuid = ce_gen_uuid(); char *id = xcalloc(strlen(uuid)+3, 1); + sprintf(id, "{%s}", uuid); - currentMark = (ce_mark *) xcalloc(sizeof (ce_mark), 1); - currentMark->id = id; - currentMark->wp = (waypoint *) waypointp; + currentMark = ce_alloc_mark(waypointp, id); ENQUEUE_TAIL(&ce_mark_head, ¤tMark->Q); - fprintf(ofd, "\t\t\t%s\n", id); // CE's departure from XML standard! + + gbfprintf(ofd, "\t\t\t%s\n", id); // CE's departure from XML standard! } /* Generate route trailer XML */ static void ce_route_tlr(const route_head *rte) { - if (doing_rtes) { - write_xml_entity_end(ofd, "\t\t", "Marks"); - write_optional_xml_entity(ofd, "\t\t", "Name", rte->rte_name); - write_xml_entity_end(ofd, "\t", "Route"); - } + write_xml_entity_end(ofd, "\t\t", "Marks"); + write_optional_xml_entity(ofd, "\t\t", "Name", rte->rte_name); + write_xml_entity_end(ofd, "\t", "Route"); } /* Generate waypoint body XML */ @@ -595,13 +590,59 @@ ce_waypt_pr(const waypoint *wp) write_optional_xml_entity(ofd, "\t\t", "Name", wp->shortname); } -/* Generate a standalone mark XML */ +static char * +ce_find_uuid(const waypoint *wpt) +{ + queue *elem, *tmp; + + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark *mark = (ce_mark *) elem; + if (mark->wp == wpt) { + return mark->id; + } + } + return NULL; +} + +static waypoint * +ce_find_wpt(const waypoint *wpt) +{ + queue *elem, *tmp; + + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark *mark = (ce_mark *) elem; + if ((mark->wp->shortname == wpt->shortname) && + (mark->wp->latitude == wpt->latitude) && + (mark->wp->longitude == wpt->longitude)) + return mark->wp; + } + return NULL; +} + +/* Generate a mark XML; look for created id's */ static void ce_mark_pr(const waypoint *wp) { + char *id; + + if (inRoute) { + id = ce_find_uuid(wp); + if (id == NULL) { + sprintf(xml_buffer, "{%s}", ce_gen_uuid()); + id = xml_buffer; + } + } + /* Have we seen and written the (nearly) same waypoint ? */ + else if (ce_find_wpt(wp) != NULL) return; + else { + ce_mark *mark = ce_alloc_mark(wp, NULL); + ENQUEUE_TAIL(&ce_mark_head, &mark->Q); + sprintf(xml_buffer, "{%s}", ce_gen_uuid()); + id = xml_buffer; + } write_xml_entity_begin2(ofd, "\t", "Mark", - "created", ce_gen_creation_time(wp->creation_time), - "id", ce_gen_uuid()); + "created", ce_gen_creation_time(wp->creation_time), + "id", id); ce_waypt_pr(wp); write_xml_entity_end(ofd, "\t", "Mark"); } @@ -611,9 +652,21 @@ static void ce_marks_pr(void) { queue *elem, *tmp; + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { ce_mark *mark = (ce_mark *) elem; ce_mark_pr(mark->wp); + } +} + +/* Release all generated marks */ +static void +ce_marks_flush_all(void) +{ + queue *elem, *tmp; + + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark *mark = (ce_mark *) elem; ce_free_mark(mark); } } @@ -634,10 +687,14 @@ ce_write(void) ce_gen_current_time()); write_xml_entity(ofd, "\t", "Name", "Navigation Objects"); + inRoute = 1; route_disp_all(ce_route_hdr, ce_route_tlr, ce_route_disp); ce_marks_pr(); + inRoute = 0; + waypt_disp_all(ce_mark_pr); - + ce_marks_flush_all(); + write_xml_entity_end(ofd, "", "NavObjectCollection"); } diff --git a/configure b/configure index 9b7086aaa..3e9773f05 100644 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.59 for GPSBabel 1.3.2. +# Generated by GNU Autoconf 2.59 for GPSBabel 1.3.3. # # Report bugs to . # @@ -269,8 +269,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='GPSBabel' PACKAGE_TARNAME='gpsbabel' -PACKAGE_VERSION='1.3.2' -PACKAGE_STRING='GPSBabel 1.3.2' +PACKAGE_VERSION='1.3.3' +PACKAGE_STRING='GPSBabel 1.3.3' PACKAGE_BUGREPORT='BUG-REPORT-ADDRESS' ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS PACKAGE_RELEASE GBMAJOR GBMINOR GBMICRO build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA SET_MAKE FILEINFO RC LIBUSBCONFIG USB_LIBS USB_CFLAGS OSJEEPS GBSER ZLIB EXPAT_LIB EFENCE_LIB GPSBABEL_DEBUG INSTALL_DEBUG DOCDIR LIBOBJS LTLIBOBJS' @@ -738,7 +738,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures GPSBabel 1.3.2 to adapt to many kinds of systems. +\`configure' configures GPSBabel 1.3.3 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -800,7 +800,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of GPSBabel 1.3.2:";; + short | recursive ) echo "Configuration of GPSBabel 1.3.3:";; esac cat <<\_ACEOF @@ -929,7 +929,7 @@ fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF -GPSBabel configure 1.3.2 +GPSBabel configure 1.3.3 generated by GNU Autoconf 2.59 Copyright (C) 2003 Free Software Foundation, Inc. @@ -943,7 +943,7 @@ cat >&5 <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by GPSBabel $as_me 1.3.2, which was +It was created by GPSBabel $as_me 1.3.3, which was generated by GNU Autoconf 2.59. Invocation command line was $ $0 $@ @@ -1281,7 +1281,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu # YYYYMMDD, please, if beta, i.e. "-beta20060413" -PACKAGE_RELEASE="" +# PACKAGE_RELEASE="-beta20061125" cat >>confdefs.h <<_ACEOF #define PACKAGE_RELEASE "$PACKAGE_RELEASE" @@ -3173,6 +3173,11 @@ else xpathdr=/sw/include/ fi ;; + *-*-freebsd*) + if test -f /usr/local/include/expat.h ; then + xpathdr=/usr/local/include + fi + ;; *) ;; esac @@ -3204,6 +3209,17 @@ cat >>confdefs.h <<\_ACEOF _ACEOF + fi + ;; + *-*-freebsd*) + if test -f /usr/local/lib/libexpat.a ; then + EXPAT_LIB=/usr/local/lib/libexpat.a + +cat >>confdefs.h <<\_ACEOF +#define HAVE_LIBEXPAT 1 +_ACEOF + + fi ;; *) @@ -3448,7 +3464,7 @@ fi done - ac_config_files="$ac_config_files Makefile xmldoc/makedoc tools/mkcapabilities win32/gpsbabel.rc coldsync/Makefile jeeps/Makefile shapelib/Makefile zlib/empty" + ac_config_files="$ac_config_files Makefile gbversion.h xmldoc/makedoc tools/mkcapabilities win32/gpsbabel.rc coldsync/Makefile jeeps/Makefile shapelib/Makefile zlib/empty" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -3812,7 +3828,7 @@ _ASBOX } >&5 cat >&5 <<_CSEOF -This file was extended by GPSBabel $as_me 1.3.2, which was +This file was extended by GPSBabel $as_me 1.3.3, which was generated by GNU Autoconf 2.59. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -3872,7 +3888,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -GPSBabel config.status 1.3.2 +GPSBabel config.status 1.3.3 configured by $0, generated by GNU Autoconf 2.59, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" @@ -3976,6 +3992,7 @@ do case "$ac_config_target" in # Handling of arguments. "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "gbversion.h" ) CONFIG_FILES="$CONFIG_FILES gbversion.h" ;; "xmldoc/makedoc" ) CONFIG_FILES="$CONFIG_FILES xmldoc/makedoc" ;; "tools/mkcapabilities" ) CONFIG_FILES="$CONFIG_FILES tools/mkcapabilities" ;; "win32/gpsbabel.rc" ) CONFIG_FILES="$CONFIG_FILES win32/gpsbabel.rc" ;; diff --git a/configure.in b/configure.in index 55b9aa081..39ce49bff 100644 --- a/configure.in +++ b/configure.in @@ -3,10 +3,10 @@ AC_PREREQ(2.59) -AC_INIT(GPSBabel, 1.3.2, BUG-REPORT-ADDRESS) +AC_INIT(GPSBabel, 1.3.3, BUG-REPORT-ADDRESS) # YYYYMMDD, please, if beta, i.e. "-beta20060413" -PACKAGE_RELEASE="" +# PACKAGE_RELEASE="-beta20061125" AC_DEFINE_UNQUOTED(PACKAGE_RELEASE, "$PACKAGE_RELEASE", [Define to the release name of this package.]) AC_SUBST(PACKAGE_RELEASE) @@ -194,6 +194,11 @@ AC_ARG_WITH(expathdr, xpathdr=/sw/include/ fi ;; + *-*-freebsd*) + if test -f /usr/local/include/expat.h ; then + xpathdr=/usr/local/include + fi + ;; *) ;; esac ] @@ -217,6 +222,13 @@ AC_ARG_WITH(libexpat, AC_SUBST(EXPAT_LIB) fi ;; + *-*-freebsd*) + if test -f /usr/local/lib/libexpat.a ; then + EXPAT_LIB=/usr/local/lib/libexpat.a + AC_DEFINE(HAVE_LIBEXPAT, 1, [Defined if you have libexpat]) + AC_SUBST(EXPAT_LIB) + fi + ;; *) EXPAT_LIB=-lexpat ;; @@ -274,5 +286,5 @@ AC_SUBST(DOCDIR) # AC_CHECK_FUNCS([atexit floor localtime_r memmove memset pow select sqrt strchr strcspn strdup strerror strncasecmp strrchr strspn strstr strtol strtoul]) AC_CHECK_FUNCS([nanosleep sleep]) -AC_CONFIG_FILES([Makefile xmldoc/makedoc tools/mkcapabilities win32/gpsbabel.rc coldsync/Makefile jeeps/Makefile shapelib/Makefile zlib/empty]) +AC_CONFIG_FILES([Makefile gbversion.h xmldoc/makedoc tools/mkcapabilities win32/gpsbabel.rc coldsync/Makefile jeeps/Makefile shapelib/Makefile zlib/empty]) AC_OUTPUT diff --git a/contrib/correctCoordinates.pl b/contrib/correctCoordinates.pl old mode 100644 new mode 100755 diff --git a/copilot.c b/copilot.c index b1b1c903b..98725740e 100644 --- a/copilot.c +++ b/copilot.c @@ -25,17 +25,41 @@ #include "coldsync/pdb.h" #include "grtcirc.h" -#define MYNAME "CoPilot Waypoint" -#define MYTYPE 0x77617970 /* wayp */ -#define MYCREATOR 0x47584255 /* GXBU */ +#define MYNAME "CoPilot Waypoint" +#define wayp_TYPE 0x77617970 /* wayp */ +#define wayu_TYPE 0x77617975 /* wayu */ +#define swpu_TYPE 0x73777075 /* swpu */ +#define GXPU_CREATOR 0x47584255 /* GXBU */ +#define AP_P_CREATOR 0x41502d50 /* AP-P */ -struct record { +struct record0 { + pdb_double latitude; /* PDB double format, */ + pdb_double longitude; /* similarly, neg = east */ + pdb_double magvar; /* magnetic variation in degrees, neg = east */ + udword elevation; /* feet */ +}; + +struct record1 { + pdb_double latitude; /* PDB double format, */ + pdb_double longitude; /* similarly, neg = east */ + pdb_double magvar; /* magnetic variation in degrees, neg = east */ + pdb_double elevation; /* feet */ +}; + +struct record3 { pdb_double latitude; /* PDB double format, */ pdb_double longitude; /* similarly, neg = east */ pdb_double magvar; /* magnetic variation in degrees, neg = east */ pdb_double elevation; /* feet */ - char flags; + char flags; /* flags */ +}; + +struct record4 { + pdb_double latitude; /* PDB double format, */ + pdb_double longitude; /* similarly, neg = east */ + pdb_float magvar; /* magnetic variation in degrees, neg = east */ + pdb_float elevation; /* feet */ }; static FILE *file_in; @@ -69,10 +93,124 @@ wr_deinit(void) fclose(file_out); } +static waypoint* +read_version0(ubyte* data) +{ + char *vdata; + waypoint *wpt_tmp; + struct record0* rec = (struct record0*)data; + + wpt_tmp = waypt_new(); + + wpt_tmp->longitude = + DEG(-pdb_read_double(&rec->longitude)); + wpt_tmp->latitude = + DEG(pdb_read_double(&rec->latitude)); + wpt_tmp->altitude = FEET_TO_METERS(be_read32(&rec->elevation)); + + vdata = (char *) data + sizeof(*rec); + + wpt_tmp->shortname = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->description = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->notes = NULL; + + return wpt_tmp; +} + +static waypoint* +read_version1(ubyte* data) +{ + char *vdata; + waypoint *wpt_tmp; + struct record1* rec = (struct record1*)data; + + wpt_tmp = waypt_new(); + + wpt_tmp->longitude = + DEG(-pdb_read_double(&rec->longitude)); + wpt_tmp->latitude = + DEG(pdb_read_double(&rec->latitude)); + wpt_tmp->altitude = + FEET_TO_METERS(pdb_read_double(&rec->elevation)); + + vdata = (char *) data + sizeof(*rec); + + wpt_tmp->shortname = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->description = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->notes = xstrdup(vdata); + + return wpt_tmp; +} + +static waypoint* +read_version3(ubyte* data) +{ + char *vdata; + waypoint *wpt_tmp; + struct record3* rec = (struct record3*)data; + + wpt_tmp = waypt_new(); + + wpt_tmp->longitude = + DEG(-pdb_read_double(&rec->longitude)); + wpt_tmp->latitude = + DEG(pdb_read_double(&rec->latitude)); + wpt_tmp->altitude = + FEET_TO_METERS(pdb_read_double(&rec->elevation)); + + vdata = (char *) data + sizeof(*rec); + + wpt_tmp->shortname = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->description = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->notes = xstrdup(vdata); + + return wpt_tmp; +} + +static waypoint* +read_version4(ubyte* data) +{ + char *vdata; + waypoint *wpt_tmp; + struct record4* rec = (struct record4*)data; + + wpt_tmp = waypt_new(); + + wpt_tmp->longitude = + DEG(-pdb_read_double(&rec->longitude)); + wpt_tmp->latitude = + DEG(pdb_read_double(&rec->latitude)); + wpt_tmp->altitude = + FEET_TO_METERS(pdb_read_float(&rec->elevation)); + + vdata = (char *) data + sizeof(*rec); + + wpt_tmp->shortname = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->description = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->notes = xstrdup(vdata); + + return wpt_tmp; +} + static void data_read(void) { - struct record *rec; struct pdb *pdb; struct pdb_record *pdb_rec; @@ -80,45 +218,47 @@ data_read(void) fatal(MYNAME ": pdb_Read failed\n"); } - if ((pdb->creator != MYCREATOR) || (pdb->type != MYTYPE)) { + if ((pdb->creator != GXPU_CREATOR && pdb->creator != AP_P_CREATOR) || + (pdb->type != wayp_TYPE && pdb->type != swpu_TYPE && + pdb->type != wayu_TYPE)) { fatal(MYNAME ": Not a CoPilot file.\n"); } + if (pdb->version > 4) { + fatal(MYNAME ": %d is not a known version.\n", pdb->version); + } + for(pdb_rec = pdb->rec_index.rec; pdb_rec; pdb_rec=pdb_rec->next) { waypoint *wpt_tmp; - char *vdata; - - wpt_tmp = waypt_new(); - - rec = (struct record *) pdb_rec->data; - wpt_tmp->longitude = - DEG(-pdb_read_double(&rec->longitude)); - wpt_tmp->latitude = - DEG(pdb_read_double(&rec->latitude)); - wpt_tmp->altitude = - pdb_read_double(&rec->elevation) * .3048; - - vdata = (char *) pdb_rec->data + sizeof(*rec); - - wpt_tmp->shortname = xstrdup(vdata); - vdata = vdata + strlen(vdata) + 1; - - wpt_tmp->description = xstrdup(vdata); - vdata = vdata + strlen(vdata) + 1; - - wpt_tmp->notes = xstrdup(vdata); + switch (pdb->version) + { + case 0: + wpt_tmp = read_version0(pdb_rec->data); + break; + case 1: + case 2: + wpt_tmp = read_version1(pdb_rec->data); + break; + case 3: + wpt_tmp = read_version3(pdb_rec->data); + break; + case 4: + wpt_tmp = read_version4(pdb_rec->data); + break; + default: + fatal(MYNAME ": Unknown version %d.\n", pdb->version); + } waypt_add(wpt_tmp); } free_pdb(pdb); } - static void copilot_writewpt(const waypoint *wpt) { - struct record *rec; + struct record4 *rec; static int ct = 0; char *vdata; @@ -126,9 +266,9 @@ copilot_writewpt(const waypoint *wpt) pdb_write_double(&rec->latitude, RAD(wpt->latitude)); pdb_write_double(&rec->longitude, RAD(-wpt->longitude)); - pdb_write_double(&rec->elevation, - wpt->altitude / .3048); - pdb_write_double(&rec->magvar, 0); + pdb_write_float(&rec->magvar, 0); + pdb_write_float(&rec->elevation, + METERS_TO_FEET(wpt->altitude)); vdata = (char *)rec + sizeof(*rec); if ( wpt->shortname ) { @@ -180,9 +320,9 @@ data_write(void) opdb->name[PDB_DBNAMELEN-1] = 0; opdb->attributes = PDB_ATTR_BACKUP; opdb->ctime = opdb->mtime = current_time() + 2082844800U; - opdb->type = MYTYPE; - opdb->creator = MYCREATOR; - opdb->version = 0; + opdb->type = wayp_TYPE; + opdb->creator = GXPU_CREATOR; + opdb->version = 4; waypt_disp_all(copilot_writewpt); diff --git a/csv_util.c b/csv_util.c index e0817d44c..3fe89dd1c 100644 --- a/csv_util.c +++ b/csv_util.c @@ -25,6 +25,7 @@ #include "csv_util.h" #include "grtcirc.h" #include "strptime.h" +#include "jeeps/gpsmath.h" #define MYNAME "CSV_UTIL" @@ -38,6 +39,7 @@ #define EXCEL_TO_TIMET(a) ((a - 25569.0) * 86400.0) #define TIMET_TO_EXCEL(a) ((a / 86400.0) + 25569.0) +#define GPS_DATUM_WGS84 118 /****************************************************************************/ /* obligatory global struct */ @@ -283,15 +285,14 @@ csv_lineparse(const char *stringstart, const char *delimited_by, #if CSVFMTS_ENABLED /*****************************************************************************/ /* dec_to_intdeg() - convert decimal degrees to integer degreees */ -/* usage: i = dec_to_intdeg(31.1234, 1); */ -/* i = dec_to_intdeg(91.1234, 0); */ +/* usage: i = dec_to_intdeg(31.1234); */ /*****************************************************************************/ static int -dec_to_intdeg(const double d, const int islat) +dec_to_intdeg(const double d) { int ideg = 0; - if (islat) { + if (d >= 0) { ideg = (2147483647) - (d * 8388608); } else { ideg = (2147483647) - (fabs(d) * 8388608) + 1; @@ -302,15 +303,14 @@ dec_to_intdeg(const double d, const int islat) /*****************************************************************************/ /* intdeg_to_dec() - convert integer degrees to decimal degreees */ -/* usage: lat = dec_to_intdeg(ilat, 1); */ -/* lon = dec_to_intdeg(ilon, 0); */ +/* usage: lat = dec_to_intdeg(ilat); */ /*****************************************************************************/ static double -intdeg_to_dec(const int ideg, const int islat) +intdeg_to_dec(const int ideg) { double d; - if (islat) { + if (ideg >= 0) { d = ((2147483647) - ideg) / (double)8388608; } else { d = ((-2147483647-1) + ideg) / (double)8388608; @@ -585,6 +585,7 @@ xcsv_file_init(void) xcsv_file.type = ff_type_file; xcsv_file.mkshort_handle = mkshort_new_handle(); + xcsv_file.gps_datum = GPS_DATUM_WGS84; } /*****************************************************************************/ @@ -688,7 +689,7 @@ sscanftime( const char *s, const char *format, const int gmt ) return mktime(&stm); } - return -1; + return 0; } static time_t @@ -834,7 +835,7 @@ xcsv_parse_val(const char *s, waypoint *wpt, const field_map_t *fmp) } else if (strcmp(fmp->key, "LAT_INT32DEG") == 0) { /* latitude as a 32 bit integer offset */ - wpt->latitude = intdeg_to_dec((int) atof(s), 1); + wpt->latitude = intdeg_to_dec((int) atof(s)); } else if ( strcmp(fmp->key, "LAT_HUMAN_READABLE") == 0) { human_to_dec( s, &wpt->latitude, &wpt->longitude, 1 ); @@ -854,7 +855,7 @@ xcsv_parse_val(const char *s, waypoint *wpt, const field_map_t *fmp) } else if (strcmp(fmp->key, "LON_INT32DEG") == 0) { /* longitude as a 32 bit integer offset */ - wpt->longitude = intdeg_to_dec((int) atof(s), 0); + wpt->longitude = intdeg_to_dec((int) atof(s)); } else if ( strcmp(fmp->key, "LON_HUMAN_READABLE") == 0) { human_to_dec( s, &wpt->latitude, &wpt->longitude, 2 ); @@ -917,7 +918,7 @@ xcsv_parse_val(const char *s, waypoint *wpt, const field_map_t *fmp) wpt->creation_time += addhms(s, fmp->printfc); } else if (strcmp(fmp->key, "ISO_TIME") == 0) { - wpt->creation_time = xml_parse_time(s); + wpt->creation_time = xml_parse_time(s, NULL); } else if (strcmp(fmp->key, "GEOCACHE_LAST_FOUND") == 0) { wpt->gc_data.last_found = yyyymmdd_to_time(s); @@ -1004,10 +1005,24 @@ xcsv_data_read(void) queue *elem, *tmp; field_map_t *fmp; ogue_t *ogp; + route_head *rte = NULL; + route_head *trk = NULL; + if (xcsv_file.datatype == trkdata) { + trk = route_head_alloc(); + track_add_head(trk); + } else + if (xcsv_file.datatype == rtedata) { + rte = route_head_alloc(); + route_add_head(rte); + } + while ((buff = gbfgetstr(xcsv_file.xcsvfp))) { linecount++; - buff = lrtrim(buff); + /* Whack trailing space; leading space may matter if our field sep + * is whitespace and we have leading whitespace. + */ + rtrim(buff); /* skip over x many lines on the top for the prologue... */ if ((xcsv_file.prologue_lines) && ((linecount - 1) < @@ -1057,7 +1072,21 @@ xcsv_data_read(void) s = csv_lineparse(NULL, xcsv_file.field_delimiter, "", linecount); } - waypt_add(wpt_tmp); + if ((xcsv_file.gps_datum > -1) && (xcsv_file.gps_datum != GPS_DATUM_WGS84)) { + double alt; + GPS_Math_Known_Datum_To_WGS84_M(wpt_tmp->latitude, wpt_tmp->longitude, 0.0, + &wpt_tmp->latitude, &wpt_tmp->longitude, &alt, xcsv_file.gps_datum); + } + switch(xcsv_file.datatype) { + case 0: + case wptdata: + waypt_add(wpt_tmp); break; + case trkdata: + track_add_wpt(trk, wpt_tmp); break; + case rtedata: + route_add_wpt(rte, wpt_tmp); break; + default: ; + } } } @@ -1086,13 +1115,14 @@ xcsv_waypt_pr(const waypoint *wpt) int i; field_map_t *fmp; queue *elem, *tmp; + double latitude, longitude; if ( oldlon < 900 ) { pathdist += radtomiles(gcdist(RAD(oldlat),RAD(oldlon), RAD(wpt->latitude),RAD(wpt->longitude))); } - oldlon = wpt->longitude; - oldlat = wpt->latitude; + longitude = oldlon = wpt->longitude; + latitude = oldlat = wpt->latitude; if (xcsv_file.field_delimiter && strcmp(xcsv_file.field_delimiter, "\\w") == 0) write_delimiter = " "; @@ -1132,12 +1162,17 @@ xcsv_waypt_pr(const waypoint *wpt) description = xstrdup(odesc); xfree(odesc); } + if ((xcsv_file.gps_datum > -1) && (xcsv_file.gps_datum != GPS_DATUM_WGS84)) { + double alt; + GPS_Math_WGS84_To_Known_Datum_M(latitude, longitude, 0.0, + &latitude, &longitude, &alt, xcsv_file.gps_datum); + } i = 0; QUEUE_FOR_EACH(xcsv_file.ofield, elem, tmp) { char *obuff; - double lat = wpt->latitude; - double lon = wpt->longitude; + double lat = latitude; + double lon = longitude; /* * A klunky concept. This should evaluate to true for any * field if we think we don't have realistic value for it. @@ -1245,7 +1280,7 @@ xcsv_waypt_pr(const waypoint *wpt) if (strcmp(fmp->key, "LAT_INT32DEG") == 0) { /* latitude as an integer offset from 0 degrees */ writebuff(buff, fmp->printfc, - dec_to_intdeg(lat, 1)); + dec_to_intdeg(lat)); } else if (strcmp(fmp->key, "LAT_HUMAN_READABLE") == 0) { dec_to_human( buff, fmp->printfc, "SN", lat ); @@ -1274,7 +1309,7 @@ xcsv_waypt_pr(const waypoint *wpt) if (strcmp(fmp->key, "LON_INT32DEG") == 0) { /* longitudee as an integer offset from 0 degrees */ writebuff(buff, fmp->printfc, - dec_to_intdeg(lon, 0)); + dec_to_intdeg(lon)); } else if (strcmp(fmp->key, "LON_HUMAN_READABLE") == 0) { dec_to_human( buff, fmp->printfc, "WE", lon ); @@ -1513,9 +1548,12 @@ xcsv_data_write(void) gbfprintf(xcsv_file.xcsvfp, "%s", xcsv_file.record_delimiter); } - waypt_disp_all(xcsv_waypt_pr); - route_disp_all(xcsv_resetpathlen,xcsv_noop,xcsv_waypt_pr); - track_disp_all(xcsv_resetpathlen,xcsv_noop,xcsv_waypt_pr); + if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == wptdata)) + waypt_disp_all(xcsv_waypt_pr); + if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == rtedata)) + route_disp_all(xcsv_resetpathlen,xcsv_noop,xcsv_waypt_pr); + if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == trkdata)) + track_disp_all(xcsv_resetpathlen,xcsv_noop,xcsv_waypt_pr); /* output epilogue lines, if any. */ QUEUE_FOR_EACH(&xcsv_file.epilogue, elem, tmp) { diff --git a/csv_util.h b/csv_util.h index 8da2d3e2a..e8659a82b 100644 --- a/csv_util.h +++ b/csv_util.h @@ -131,7 +131,11 @@ typedef struct { short_handle mkshort_handle;/* handle for mkshort() */ ff_type type; /* format type for GUI wrappers. */ - + + int gps_datum; /* result of GPS_Lookup_Datum_Index */ + gpsdata_type datatype; /* can be wptdata, rtedata or trkdata */ + /* ... or ZERO to keep the old behaviour */ + } xcsv_file_t; diff --git a/defs.h b/defs.h index 3c2d5ad93..0c8e081a5 100644 --- a/defs.h +++ b/defs.h @@ -151,8 +151,8 @@ typedef struct { gpsdata_type objective; unsigned int masked_objective; int verbose_status; /* set by GUI wrappers for status */ - int no_smart_icons; - int no_smart_names; + int smart_icons; + int smart_names; cet_cs_vec_t *charset; char *charset_name; inifile_t *inifile; @@ -163,6 +163,11 @@ extern const char gpsbabel_version[]; extern time_t gpsbabel_now; /* gpsbabel startup-time; initialized in main.c with time() */ extern time_t gpsbabel_time; /* gpsbabel startup-time; initialized in main.c with current_time(), ! ZERO within testo ! */ +#define MILLI_TO_MICRO(t) (t * 1000) /* Milliseconds to Microseconds */ +#define MICRO_TO_MILLI(t) (t / 1000) /* Microseconds to Milliseconds*/ +#define CENTI_TO_MICRO(t) (t * 10000) /* Centiseconds to Microseconds */ +#define MICRO_TO_CENTI(t) (t / 10000) /* Centiseconds to Microseconds */ + /* Short or Long XML Times */ #define XML_SHORT_TIME 1 #define XML_LONG_TIME 2 @@ -326,7 +331,7 @@ typedef struct { wp_flags wpt_flags; const char *icon_descr; time_t creation_time; /* standardized in UTC/GMT */ - int centiseconds; /* Optional hundredths of a second. */ + int microseconds; /* Optional millionths of a second. */ /* * route priority is for use by the simplify filter. If we have @@ -726,6 +731,8 @@ char * convert_human_date_format(const char *human_datef); /* "MM,YYYY,DD" -> "% char * convert_human_time_format(const char *human_timef); /* "HH+mm+ss" -> "%H+%M+%S" */ char * pretty_deg_format(double lat, double lon, char fmt, int html); /* decimal -> dd.dddd or dd mm.mmm or dd mm ss */ +char * get_filename(const char *fname); /* extract the filename portion */ + /* * Character encoding transformations. */ @@ -743,7 +750,7 @@ char * pretty_deg_format(double lat, double lon, char fmt, int html); /* decim #define str_iso8859_1_to_utf8(str) cet_str_iso8859_1_to_utf8((str)) /* this lives in gpx.c */ -time_t xml_parse_time( const char *cdatastr ); +time_t xml_parse_time( const char *cdatastr, int * microsecs ); xml_tag *xml_findfirst( xml_tag *root, char *tagname ); xml_tag *xml_findnext( xml_tag *root, xml_tag *cur, char *tagname ); @@ -773,6 +780,10 @@ typedef struct { unsigned char data[8]; } pdb_double; +typedef struct { + unsigned char data[4]; +} pdb_float; + /* * Protypes for Endianness helpers. */ @@ -786,13 +797,26 @@ void be_write16(void *pp, const unsigned i); void be_write32(void *pp, const unsigned i); void le_write16(void *pp, const unsigned i); void le_write32(void *pp, const unsigned i); -double pdb_read_double(void *p); -void pdb_write_double(void *pp, double d); -double le_read_double(void *p); +double endian_read_double(void* ptr, int read_le); +float endian_read_float(void* ptr, int read_le); +void endian_write_double(void* ptr, double d, int write_le); +void endian_write_float(void* ptr, float f, int write_le); + +float be_read_float(void *p); double be_read_double(void *p); -void le_write_double(void *p, double d); -void be_write_double(void *p, double d); +void be_write_float(void *pp, float d); +void be_write_double(void *pp, double d); + +float le_read_float(void *p); +double le_read_double(void *p); +void le_write_float(void *ptr, float f); +void le_write_double(void *p, double d); + +#define pdb_write_float be_write_float +#define pdb_read_float be_read_float +#define pdb_write_double be_write_double +#define pdb_read_double be_read_double /* * Prototypes for generic conversion routines (util.c). diff --git a/discard.c b/discard.c index 1b69c8c86..d8f1942c5 100644 --- a/discard.c +++ b/discard.c @@ -28,6 +28,8 @@ static char *vdopopt = NULL; static char *andopt = NULL; static double hdopf; static double vdopf; +static gpsdata_type what; +static route_head *head; static arglist_t fix_args[] = { @@ -62,35 +64,43 @@ fix_process_wpt(const waypoint *wpt) del = delh || delv; if (del) { - waypt_del(waypointp); + switch(what) { + case wptdata: + waypt_del(waypointp); + break; + case trkdata: + track_del_wpt(head, waypointp); + break; + case rtedata: + route_del_wpt(head, waypointp); + break; + default: + return; + } waypt_free(waypointp); } } static void -fix_process_track(const route_head *trk) +fix_process_head(const route_head *trk) { - waypoint * waypointp; - queue *elem, *tmp; - - QUEUE_FOR_EACH((queue *)&trk->waypoint_list, elem, tmp) { - waypointp = (waypoint *)elem; - - fix_process_wpt(waypointp); - } + head = (route_head *)trk; } static void fix_process(void) { // Filter waypoints. + what = wptdata; waypt_disp_all(fix_process_wpt); // Filter tracks - track_disp_all(fix_process_track, NULL, NULL); + what = trkdata; + track_disp_all(fix_process_head, NULL, fix_process_wpt); // And routes - route_disp_all(fix_process_track, NULL, NULL); + what = rtedata; + route_disp_all(fix_process_head, NULL, fix_process_wpt); } diff --git a/dmtlog.c b/dmtlog.c index 05d70b055..785ab0050 100644 --- a/dmtlog.c +++ b/dmtlog.c @@ -128,6 +128,15 @@ finalize_pt(waypoint *wpt) wpt->latitude = xmlLatitude; wpt->longitude = xmlLongitude; } + /* NOTE: + * Alan White reports this program actually subtracts a number + * of meters ranging between 46 and 50 meters. It appears to be + * constant for each location, but different without an obvious + * correlation to ground altitude. We considered offsetting this + * in GPSBabel, but concluded it wasn't worth the bother. + * If we get complaints, probably all of our alt reading and writing + * should offset an average of 46m or so. + */ wpt->altitude = xmlAltitude; convert_datum(wpt, xmldatum); } @@ -649,7 +658,7 @@ track_wpt_cb(const waypoint *wpt) gbfputdbl(wpt->latitude, fout); gbfputdbl(wpt->longitude, fout); - gbfputdbl(wpt->altitude, fout); + gbfputdbl(wpt->altitude != unknown_alt ? wpt->altitude : 0, fout); } static void @@ -659,7 +668,7 @@ wpt_cb(const waypoint *wpt) gbfputdbl(wpt->latitude, fout); gbfputdbl(wpt->longitude, fout); - gbfputdbl(wpt->altitude, fout); + gbfputdbl(wpt->altitude != unknown_alt ? wpt->altitude : 0, fout); names = 1; if (wpt->description && *wpt->description) names = 2; @@ -680,7 +689,7 @@ dmtlog_write(void) gbfputint32(4, fout); gbfputint32(1, fout); gbfputint32(0x100001, fout); - gbfputuint32((const gbuint32)gpsbabel_now, fout); + gbfputuint32((const gbuint32)gpsbabel_time, fout); header_written = 0; this_index = 0; diff --git a/easygps.c b/easygps.c index b203ada69..2bc95850b 100644 --- a/easygps.c +++ b/easygps.c @@ -22,8 +22,8 @@ #include "defs.h" #include -static FILE *file_in; -static FILE *file_out; +static gbfile *file_in; +static gbfile *file_out; static short_handle mkshort_handle; /* static char *deficon = NULL; */ @@ -39,139 +39,96 @@ arglist_t easygps_args[] = { static void rd_init(const char *fname) { + int sz; char ibuf[100] = {'0'} ; const char *ezsig = "TerraByte Location File"; - file_in = xfopen(fname, "rb", MYNAME); + file_in = gbfopen_le(fname, "rb", MYNAME); - fread(ibuf, 52, 1, file_in); + sz = gbfread(ibuf, 1, 52, file_in); - if (strncmp(ibuf, ezsig, sizeof(ezsig)-1) || - ibuf[51] != 'W') { - fatal(MYNAME ": %s is not an EasyGPS file\n", fname); + if ((sz < 52) || + strncmp(ibuf, ezsig, sizeof(ezsig)-1) || + (ibuf[51] != 'W')) { + fatal(MYNAME ": %s is not an EasyGPS file.\n", fname); } } static void rd_deinit(void) { - fclose(file_in); + gbfclose(file_in); } static void wr_init(const char *fname) { - file_out = xfopen(fname, "wb", MYNAME); + file_out = gbfopen_le(fname, "wb", MYNAME); mkshort_handle = mkshort_new_handle(); } static void wr_deinit(void) { - fclose(file_out); + gbfclose(file_out); mkshort_del_handle(&mkshort_handle); } -/* - * Read a pascal string from file_in and return a copy in allocated - * storage. - */ -static void * -pas_read(void) -{ - char *d; - int ilen; - - ilen = fgetc(file_in); - d = (char *) xmalloc(ilen + 1); - fread(d, ilen, 1, file_in); - d[ilen] = 0; - return d; -} - static void data_read(void) { char p; char ibuf[10]; - char bbuf[4096]; - char *bbufp; do { unsigned char tag; waypoint *wpt_tmp; wpt_tmp = waypt_new(); - for (tag = fgetc(file_in); tag != 0xff; tag = fgetc(file_in)) { + for (tag = gbfgetc(file_in); tag != 0xff; tag = gbfgetc(file_in)) { switch (tag) { case 1: - wpt_tmp->shortname = (char *) pas_read(); + wpt_tmp->shortname = gbfgetpstr(file_in); break; case 2: case 3: - wpt_tmp->description = (char *) pas_read(); + wpt_tmp->description = gbfgetpstr(file_in);; break; case 5: - wpt_tmp->notes = (char *) pas_read(); + wpt_tmp->notes = gbfgetpstr(file_in);; break; case 6: - wpt_tmp->url_link_text = (char *) pas_read(); + wpt_tmp->url_link_text = gbfgetpstr(file_in);; break; case 7: - wpt_tmp->icon_descr = (char *) pas_read(); + wpt_tmp->icon_descr = gbfgetpstr(file_in);; wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; break; case 8: /* NULL Terminated (vs. pascal) descr */ - bbufp = bbuf; - for(;;) { - p = fgetc(file_in); - *bbufp++ = p; - if ( 0 == p ) { - break; - } - } - wpt_tmp->notes = xstrdup(bbuf); + wpt_tmp->notes = gbfgetcstr(file_in); break; case 9: /* NULL Terminated (vs. pascal) link */ - bbufp = bbuf; - for(;;) { - p = fgetc(file_in); - *bbufp++ = p; - if ( 0 == p ) { - break; - } - } - wpt_tmp->url = xstrdup(bbuf); + wpt_tmp->url = gbfgetcstr(file_in); break; case 0x10: - bbufp = bbuf; - for(;;) { - p = fgetc(file_in); - *bbufp++ = p; - if ( 0 == p ) { - break; - } - } - wpt_tmp->url_link_text = xstrdup(bbuf); + wpt_tmp->url_link_text = gbfgetcstr(file_in); break; case 0x63: - fread(ibuf, 8, 1, file_in); - wpt_tmp->latitude = le_read_double(ibuf); + wpt_tmp->latitude = gbfgetdbl(file_in); break; case 0x64: - fread(ibuf, 8, 1, file_in); - wpt_tmp->longitude = le_read_double(ibuf); + wpt_tmp->longitude = gbfgetdbl(file_in); break; case 0x65: case 0x66: - fread(ibuf, 8, 1, file_in); + gbfread(ibuf, 8, 1, file_in); break; case 0x84: case 0x85: - fread(ibuf, 4, 1, file_in); + gbfread(ibuf, 4, 1, file_in); break; case 0x86: /* May be proximity. I think it's time. */ - fread(ibuf, 4, 1, file_in); + gbfread(ibuf, 4, 1, file_in); break; default: printf("Unknown tag %x\n", tag); @@ -179,63 +136,47 @@ data_read(void) } } waypt_add(wpt_tmp); - p = fgetc(file_in); - } while (!feof(file_in) && (p == 'W')); + p = gbfgetc(file_in); + } while (!gbfeof(file_in) && (p == 'W')); } - - /* - * Write a Pascal string to the output stream. - */ -static void -write_pstring(const char *p) -{ - int len = strlen(p); - if (len > 255) { - fatal(MYNAME ": String too long at %d bytes\n", len); - } - fputc(len, file_out); - fwrite(p, len, 1, file_out); -} - static void ez_disp(const waypoint *wpt) { - char tbuf[8]; - fprintf(file_out, "W"); + gbfputc('W', file_out); + if (wpt->shortname) { - fputc(1, file_out); - write_pstring(wpt->shortname); + gbfputc(1, file_out); + gbfputpstr(wpt->shortname, file_out); } if (wpt->description) { - fputc(3, file_out); - write_pstring(wpt->description); + gbfputc(3, file_out); + gbfputpstr(wpt->description, file_out); } if (wpt->icon_descr) { - fputc(7, file_out); - write_pstring(wpt->icon_descr); + gbfputc(7, file_out); + gbfputpstr(wpt->icon_descr, file_out); } - fputc(0x63, file_out); - le_write_double(tbuf, wpt->latitude); - fwrite(tbuf, 8, 1, file_out); - fputc(0x64, file_out); - le_write_double(tbuf, wpt->longitude); - fwrite(tbuf, 8, 1, file_out); + gbfputc(0x63, file_out); + gbfputdbl(wpt->latitude, file_out); + + gbfputc(0x64, file_out); + gbfputdbl(wpt->longitude, file_out); + if (wpt->notes) { - fputc(5, file_out); - write_pstring(wpt->notes); + gbfputc(5, file_out); + gbfputpstr(wpt->notes, file_out); } if (wpt->url_link_text) { - fputc(6, file_out); - write_pstring(wpt->url_link_text); + gbfputc(6, file_out); + gbfputpstr(wpt->url_link_text, file_out); } if (1 && wpt->url) { - fputc(9, file_out); - fputs(wpt->url, file_out); - fputc(0, file_out); + gbfputc(9, file_out); + gbfputcstr(wpt->url, file_out); } - fputc(0xff, file_out); + gbfputc(0xff, file_out); } static void @@ -243,19 +184,19 @@ data_write(void) { setshort_length(mkshort_handle, 6); - fprintf(file_out, + gbfprintf(file_out, "TerraByte Location File Copyright 2001 TopoGrafix\n"); /* * I don't know what this is. */ - fprintf(file_out, "%c", 0xb); + gbfprintf(file_out, "%c", 0xb); waypt_disp_all(ez_disp); /* * Files seem to always end in a zero. */ - fputc(0x00, file_out); + gbfputc(0x00, file_out); } diff --git a/filter_vecs.c b/filter_vecs.c index 8dee6d560..75e4a5e1c 100644 --- a/filter_vecs.c +++ b/filter_vecs.c @@ -115,7 +115,7 @@ fl_vecs_t filter_vec_list[] = { { &transform_vecs, "transform", - "Transformate waypoints into a route, tracks into routes, ..." + "Transform waypoints into a route, tracks into routes, ..." }, #endif { diff --git a/garmin.c b/garmin.c index c696357b0..51517774b 100644 --- a/garmin.c +++ b/garmin.c @@ -42,8 +42,10 @@ static char *snwhiteopt = NULL; static char *deficon = NULL; static char *category = NULL; +#define MILITANT_VALID_WAYPT_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + /* Technically, even this is a little loose as spaces arent allowed */ -static char valid_waypt_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789"; +static const char *valid_waypt_chars = MILITANT_VALID_WAYPT_CHARS " "; static arglist_t garmin_args[] = { @@ -133,6 +135,14 @@ rw_init(const char *fname) case 130: /* Garmin Etrex (yellow) */ receiver_short_length = 6; break; + case 295: + /* eTrex (yellow, firmware v. 3.30) */ + receiver_short_length = 6; + valid_waypt_chars = + MILITANT_VALID_WAYPT_CHARS " +-"; + setshort_badchars(mkshort_handle, "\"$.,'!"); + break; + case 155: /* Garmin V */ case 404: /* SP2720 */ receiver_short_length = 20; @@ -284,6 +294,7 @@ waypt_read(void) waypt_add(wpt_tmp); GPS_Way_Del(&way[i]); } + xfree(way); } static @@ -435,7 +446,7 @@ pvt2wpt(GPS_PPvt_Data pvt, waypoint *wpt) - pvt->leap_scnds; wptimes = floor(wptime); wpt->creation_time = wptimes; - wpt->centiseconds = 100.0 * (wptime - wptimes); + wpt->microseconds = 1000000.0 * (wptime - wptimes); /* * The Garmin spec fifteen different models that use a different @@ -476,6 +487,8 @@ pvt_read(posn_status *posn_status) if (GPS_Command_Pvt_Get(&pvt_fd, &pvt)) { pvt2wpt(pvt, wpt); + GPS_Pvt_Del(&pvt); + wpt->shortname = xstrdup("Position"); if (gps_errno && posn_status) { @@ -493,6 +506,7 @@ pvt_read(posn_status *posn_status) fatal(MYNAME ": Fatal error reading position.\n"); } + waypt_free(wpt); GPS_Pvt_Del(&pvt); return NULL; @@ -558,16 +572,18 @@ waypt_write_cb(GPS_PWay *way) } /* - * If we're not using smart icons, try to put the cache info in the + * If we're using smart names, try to put the cache info in the * description. */ const char * get_gc_info(waypoint *wpt) { - if (global_opts.no_smart_icons) { + if (global_opts.smart_names) { if (wpt->gc_data.type == gt_virtual) return "V "; if (wpt->gc_data.type == gt_unknown) return "? "; if (wpt->gc_data.type == gt_multi) return "Mlt "; + if (wpt->gc_data.type == gt_earth) return "EC "; + if (wpt->gc_data.type == gt_event) return "Ev "; if (wpt->gc_data.container == gc_micro) return "M "; if (wpt->gc_data.container == gc_small) return "S "; } @@ -622,7 +638,7 @@ waypoint_write(void) } way[i]->ident[sizeof(way[i]->ident)-1] = 0; - if (!global_opts.no_smart_icons && + if (global_opts.smart_names && wpt->gc_data.diff && wpt->gc_data.terr) { snprintf(obuf, sizeof(obuf), "%s%d/%d %s", get_gc_info(wpt), diff --git a/garmin_fs.c b/garmin_fs.c index b22621ea3..47afd54c8 100644 --- a/garmin_fs.c +++ b/garmin_fs.c @@ -96,7 +96,7 @@ void garmin_fs_copy(garmin_fs_t **dest, garmin_fs_t *src) /* GPX - out */ void -garmin_fs_xml_fprint(FILE *ofd, const waypoint *waypt) +garmin_fs_xml_fprint(gbfile *ofd, const waypoint *waypt) { garmin_fs_t *gmsd = GMSD_FIND(waypt); if (gmsd == NULL) return; @@ -109,18 +109,18 @@ garmin_fs_xml_fprint(FILE *ofd, const waypoint *waypt) { int space = 1; - fprintf(ofd, "%*s\n", space++ * 2, ""); - fprintf(ofd, "%*s\n", space++ * 2, ""); + gbfprintf(ofd, "%*s\n", space++ * 2, ""); if (gmsd->flags.proximity) - fprintf(ofd, "%*s%.6f\n", space * 2, "", gmsd->proximity); + gbfprintf(ofd, "%*s%.6f\n", space * 2, "", gmsd->proximity); if (gmsd->flags.temperature) - fprintf(ofd, "%*s%.6f\n", space * 2, "", gmsd->temperature); + gbfprintf(ofd, "%*s%.6f\n", space * 2, "", gmsd->temperature); if (gmsd->flags.depth) - fprintf(ofd, "%*s%.6f\n", space * 2, "", gmsd->depth); + gbfprintf(ofd, "%*s%.6f\n", space * 2, "", gmsd->depth); if (gmsd->flags.display) { char *cx; @@ -136,23 +136,23 @@ garmin_fs_xml_fprint(FILE *ofd, const waypoint *waypt) cx = "SymbolAndName"; break; } - fprintf(ofd, "%*s%s\n", space * 2, "", cx); + gbfprintf(ofd, "%*s%s\n", space * 2, "", cx); } if (gmsd->flags.category && gmsd->category) { int i; gbuint16 cx = gmsd->category; - fprintf(ofd, "%*s\n", space++ * 2, ""); + gbfprintf(ofd, "%*s\n", space++ * 2, ""); for (i = 0; i < 16; i++) { if (cx & 1) - fprintf(ofd, "%*sCategory %d\n", space*2, "", i+1); + gbfprintf(ofd, "%*sCategory %d\n", space*2, "", i+1); cx = cx >> 1; } - fprintf(ofd, "%*s\n", --space * 2, ""); + gbfprintf(ofd, "%*s\n", --space * 2, ""); } - fprintf(ofd, "%*s\n", --space * 2, ""); - fprintf(ofd, "%*s\n", --space * 2, ""); + gbfprintf(ofd, "%*s\n", --space * 2, ""); + gbfprintf(ofd, "%*s\n", --space * 2, ""); } } diff --git a/garmin_fs.h b/garmin_fs.h index 123525123..f12a11a8e 100644 --- a/garmin_fs.h +++ b/garmin_fs.h @@ -106,7 +106,7 @@ char *garmin_fs_xstrdup(const char *src, size_t size); /* for GPX */ void garmin_fs_xml_convert(const int base_tag, int tag, const char *cdatastr, waypoint *waypt); -void garmin_fs_xml_fprint(FILE *ofd, const waypoint *waypt); +void garmin_fs_xml_fprint(gbfile *ofd, const waypoint *waypt); /* common garmin_fs utilities */ diff --git a/garmin_tables.c b/garmin_tables.c index 5e0811f9c..a82369967 100644 --- a/garmin_tables.c +++ b/garmin_tables.c @@ -3,7 +3,7 @@ Based on information provided by Ian Cowley, Sigurd Humerfelt, and Garmin MapSource - Copyright (C) 2003 Robert Lipe, robertlipe@usa.net + Copyright (C) 2003-2007 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -94,8 +94,8 @@ icon_mapping_t garmin_icon_table[] = { { 99, 8239, "Ghost Town" }, { 113, 16393, "Glider Area" }, { 68, 8197, "Golf Course" }, - { 2, 2, "Green Diamond" }, - { 15, 15, "Green Square" }, + { 2, 2, "Diamond, Green" }, + { 15, 15, "Square, Green" }, { 108, 16388, "Heliport" }, { 9, 9, "Horn" }, { 57, 171, "Hunting Area" }, @@ -106,7 +106,7 @@ icon_mapping_t garmin_icon_table[] = { { 59, 173, "Lodging" }, { 59, 173, "Hotel" }, { 20, 21, "Man Overboard" }, - { 0, 0, "Marina" }, + { 0, 0, "Anchor" }, { 43, 156, "Medical Facility" }, { 66, 8195, "Mile Marker" }, { 101, 8241, "Military" }, @@ -137,8 +137,8 @@ icon_mapping_t garmin_icon_table[] = { { 83, 8214, "Post Office" }, { 109, 16389, "Private Field" }, { 36, 37, "Radio Beacon" }, - { 3, 3, "Red Diamond" }, - { 16, 16, "Red Square" }, + { 3, 3, "Diamond, Red" }, + { 16, 16, "Square, Red" }, { 10, 10, "Residence" }, { 10, 10, "House" }, { 11, 11, "Restaurant" }, @@ -169,8 +169,8 @@ icon_mapping_t garmin_icon_table[] = { { 114, 16394, "Ultralight Area" }, { 139, 8282, "Water Hydrant" }, /* new in MapSource V5 */ { 18, 18, "Waypoint" }, - { 17, 17, "White Buoy" }, - { 35, 36, "White Dot" }, + { 17, 17, "Buoy, White" }, + { 35, 36, "Dot, White" }, { 88, 8219, "Zoo" }, /* Custom icons. The spec reserves 7680-8191 for the custom @@ -200,9 +200,9 @@ icon_mapping_t garmin_icon_table[] = { { 143, 8289, "Pin, Red" }, { 144, 8287, "Pin, Blue" }, { 145, 8288, "Pin, Green" }, - { 146, 8292, "Diamond, Red" }, - { 147, 8290, "Diamond, Blue" }, - { 148, 8291, "Diamond, Green" }, + { 146, 8292, "Block, Red" }, + { 147, 8290, "Block, Blue" }, + { 148, 8291, "Block, Green" }, { 149, 8293, "Bike Trail" }, { 150, 181, "Fishing Hot Spot Facility" }, { 151, 8249, "Police Station"}, @@ -216,31 +216,34 @@ icon_mapping_t garmin_icon_table[] = { { 159, 188, "Weed Bed" }, { 160, 189, "Dropoff" }, { 161, 190, "Dock" }, + { 162, 191, "Marina" }, + { 163, 192, "Bait and Tackle" }, + { 164, 193, "Stump" }, /* New in Garmin protocol spec from June 2006. Extracted from * spec and fed through some horrible awk to add ones we didn't * have before but normalized for consistency. */ { -1, 8359, "Asian Food" }, - { -1, 8296, "Blue Circle" }, - { -1, 8299, "Blue Diamond" }, - { -1, 8317, "Blue Letter A" }, - { -1, 8318, "Blue Letter B" }, - { -1, 8319, "Blue Letter C" }, - { -1, 8320, "Blue Letter D" }, - { -1, 8341, "Blue Number 0" }, - { -1, 8342, "Blue Number 1" }, - { -1, 8343, "Blue Number 2" }, - { -1, 8344, "Blue Number 3" }, - { -1, 8345, "Blue Number 4" }, - { -1, 8346, "Blue Number 5" }, - { -1, 8347, "Blue Number 6" }, - { -1, 8348, "Blue Number 7" }, - { -1, 8349, "Blue Number 8" }, - { -1, 8350, "Blue Number 9" }, - { -1, 8302, "Blue Oval" }, - { -1, 8305, "Blue Rectangle" }, - { -1, 8308, "Blue Square" }, - { -1, 8351, "Blue Triangle" }, + { 167, 8296, "Circle, Blue" }, + { 168, 8299, "Diamond, Blue" }, + { 178, 8317, "Letter A, Blue" }, + { 181, 8318, "Letter B, Blue" }, + { 184, 8319, "Letter C, Blue" }, + { 187, 8320, "Letter D, Blue" }, + { 190, 8341, "Number 0, Blue" }, + { 193, 8342, "Number 1, Blue" }, + { 196, 8343, "Number 2, Blue" }, + { 199, 8344, "Number 3, Blue" }, + { 202, 8345, "Number 4, Blue" }, + { 205, 8346, "Number 5, Blue" }, + { 208, 8347, "Number 6, Blue" }, + { 211, 8348, "Number 7, Blue" }, + { 214, 8349, "Number 8, Blue" }, + { 217, 8350, "Number 9, Blue" }, + { 171, 8302, "Oval, Blue" }, + { 174, 8305, "Rectangle, Blue" }, + { 175, 8308, "Square, Blue" }, + { 218, 8351, "Triangle, Blue" }, { -1, 8254, "Border Crossing (Port Of Entry)" }, { -1, 182, "Bottom Conditions" }, { -1, 8360, "Deli" }, @@ -251,24 +254,24 @@ icon_mapping_t garmin_icon_table[] = { { -1, 8232, "Geographic place name, land" }, { -1, 8230, "Geographic place name, Man-made" }, { -1, 8231, "Geographic place name, water" }, - { -1, 8295, "Green circle" }, - { -1, 8313, "Green Letter A" }, - { -1, 8315, "Green Letter B" }, - { -1, 8314, "Green Letter C" }, - { -1, 8316, "Green Letter D" }, - { -1, 8331, "Green Number 0" }, - { -1, 8332, "Green Number 1" }, - { -1, 8333, "Green Number 2" }, - { -1, 8334, "Green Number 3" }, - { -1, 8335, "Green Number 4" }, - { -1, 8336, "Green Number 5" }, - { -1, 8337, "Green Number 6" }, - { -1, 8338, "Green Number 7" }, - { -1, 8339, "Green Number 8" }, - { -1, 8340, "Green Number 9" }, - { -1, 8301, "Green Oval" }, - { -1, 8304, "Green Rectangle" }, - { -1, 8352, "Green Triangle" }, + { 166, 8295, "Circle, Green" }, + { 177, 8313, "Letter A, Green" }, + { 180, 8315, "Letter B, Green" }, + { 183, 8314, "Letter C, Green" }, + { 186, 8316, "Letter D, Green" }, + { 189, 8331, "Number 0, Green" }, + { 192, 8332, "Number 1, Green" }, + { 195, 8333, "Number 2, Green" }, + { 198, 8334, "Number 3, Green" }, + { 201, 8335, "Number 4, Green" }, + { 204, 8336, "Number 5, Green" }, + { 207, 8337, "Number 6, Green" }, + { 210, 8338, "Number 7, Green" }, + { 213, 8339, "Number 8, Green" }, + { 216, 8340, "Number 9, Green" }, + { 170, 8301, "Oval, Green" }, + { 173, 8304, "Rectangle, Green" }, + { 219, 8352, "Triangle, Green" }, { -1, 16385, "Intersection" }, { -1, 8201, "Intl freeway hwy" }, { -1, 8202, "Intl national hwy" }, @@ -281,24 +284,24 @@ icon_mapping_t garmin_icon_table[] = { { -1, 168, "Null" }, { -1, 180, "Open 24 Hours" }, { -1, 8222, "Ramp intersection" }, - { -1, 8294, "Red circle" }, - { -1, 8309, "Red Letter A" }, - { -1, 8310, "Red Letter B" }, - { -1, 8311, "Red Letter C" }, - { -1, 8312, "Red Letter D" }, - { -1, 8321, "Red Number 0" }, - { -1, 8322, "Red Number 1" }, - { -1, 8323, "Red Number 2" }, - { -1, 8324, "Red Number 3" }, - { -1, 8325, "Red Number 4" }, - { -1, 8326, "Red Number 5" }, - { -1, 8327, "Red Number 6" }, - { -1, 8328, "Red Number 7" }, - { -1, 8329, "Red Number 8" }, - { -1, 8330, "Red Number 9" }, - { -1, 8300, "Red Oval" }, - { -1, 8303, "Red Rectangle" }, - { -1, 8353, "Red Triangle" }, + { 165, 8294, "Circle, Red" }, + { 176, 8309, "Letter A, Red" }, + { 179, 8310, "Letter B, Red" }, + { 182, 8311, "Letter C, Red" }, + { 185, 8312, "Letter D, Red" }, + { 188, 8321, "Number 0, Red" }, + { 191, 8322, "Number 1, Red" }, + { 194, 8323, "Number 2, Red" }, + { 197, 8324, "Number 3, Red" }, + { 200, 8325, "Number 4, Red" }, + { 203, 8326, "Number 5, Red" }, + { 206, 8327, "Number 6, Red" }, + { 209, 8328, "Number 7, Red" }, + { 212, 8329, "Number 8, Red" }, + { 215, 8330, "Number 9, Red" }, + { 169, 8300, "Oval, Red" }, + { 172, 8303, "Rectangle, Red" }, + { 220, 8353, "Triangle, Red" }, { -1, 8362, "Seafood" }, { -1, 8194, "State Hwy" }, { -1, 8363, "Steak" }, @@ -311,6 +314,37 @@ icon_mapping_t garmin_icon_table[] = { { -1, 16387, "VHF Omni-range" }, { -1, 16397, "VOR-DME" }, { -1, 16396, "VOR/TACAN" }, + + /* This block new on 1/15 from the Mapsource 6.12 beta */ + { 221, -1, "Contact, Blonde" }, + { 222, -1, "Contact, Clown" }, + { 223, -1, "Contact, Glasses" }, + { 224, -1, "Contact, Panda" }, + { 225, -1, "Multi-Cache" }, + { 226, -1, "Letterbox Cache" }, + { 227, -1, "Puzzle Cache" }, + { 228, -1, "Library" }, + { 229, -1, "Ground Transportation" }, + { 230, -1, "City Hall" }, + { 231, -1, "Winery" }, + { 232, -1, "ATV" }, + { 233, -1, "Big Game" }, + { 234, -1, "Blind" }, + { 235, -1, "Blood Trail" }, + { 236, -1, "Cover" }, + { 237, -1, "Covey" }, + { 238, -1, "Food Source" }, + { 239, -1, "Furbearer" }, + { 240, -1, "Lodge" }, + { 241, -1, "Small Game" }, + { 242, -1, "Animal Tracks" }, + { 243, -1, "Treed Quarry" }, + { 244, -1, "Tree Stand" }, + { 245, -1, "Truck" }, + { 246, -1, "Upland Game" }, + { 247, -1, "Waterfowl" }, + { 248, -1, "Water Source" }, + { -1, -1, NULL }, }; @@ -651,6 +685,7 @@ gt_find_desc_from_icon_number(const int icon, garmin_formats_e garmin_format, in int gt_find_icon_number_from_desc(const char *desc, garmin_formats_e garmin_format) { + static int find_flag = 0; icon_mapping_t *i; int def_icon = DEFAULT_ICON_VALUE; int n; @@ -691,6 +726,37 @@ int gt_find_icon_number_from_desc(const char *desc, garmin_formats_e garmin_form } } } + + /* + * try to handle some complex icon names: i.e. "Blue Diamond" and "Diamond, Blue" + * "find_flag" prevents us from a possible endless loop + */ + + if (find_flag == 0) + { + char **prefix; + char *prefixes[] = {"White ", "Red ", "Green ", "Blue ", "Black ", NULL}; + + for (prefix = prefixes; *prefix != NULL; prefix++) + { + int len = strlen(*prefix); + + if (case_ignore_strncmp(desc, *prefix, len) == 0) + { + char buff[64]; + int result; + + snprintf(buff, sizeof(buff), "%s, %s", &desc[len], *prefix); + rtrim(buff); + + find_flag = 1; + result = gt_find_icon_number_from_desc(buff, garmin_format); + find_flag = 0; + + return result; + } + } + } return def_icon; } @@ -767,3 +833,38 @@ gt_get_icao_cc(const char *country, const char *shortname) } while (x->country != NULL); return NULL; } + +#if MAKE_TABLE + +/* + * Used to generate icon tables in appendix. + * cc -DMAKE_TABLE garmin_tables.c fatal.o util.o globals.o -lm + */ + +int cet_utf8_to_ucs4(const char *str, int *bytes, int *value) +{ + fatal("Should not be here."); +} + + +int +sortem(const void *a, const void *b) +{ + const icon_mapping_t *aa = a; + const icon_mapping_t *bb = b; + +// return aa->mpssymnum - bb->mpssymnum; + return strcmp(aa->icon, bb->icon); + +} + +main() +{ + icon_mapping_t *i; + qsort(garmin_icon_table, sizeof(garmin_icon_table) / sizeof(garmin_icon_table[0]) - 1, sizeof(garmin_icon_table[0]), sortem); + for (i = garmin_icon_table; i->icon; i++) { +// printf("%03d\t%s\n", i->mpssymnum, i->icon); + printf("%s\n", i->icon); + } +} +#endif diff --git a/garmin_txt.c b/garmin_txt.c index 9de5d56e7..d1dc1eb79 100644 --- a/garmin_txt.c +++ b/garmin_txt.c @@ -96,12 +96,14 @@ static char *opt_date_format = NULL; static char *opt_time_format = NULL; static char *opt_precision = NULL; static char *opt_utc = NULL; +static char *opt_grid = NULL; static arglist_t garmin_txt_args[] = { {"date", &opt_date_format, "Read/Write date format (i.e. yyyy/mm/dd)", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, {"datum", &opt_datum, "GPS datum (def. WGS 84)", "WGS 84", ARGTYPE_STRING, ARG_NOMINMAX}, {"dist", &opt_dist, "Distance unit [m=metric, s=statute]", "m", ARGTYPE_STRING, ARG_NOMINMAX}, + {"grid", &opt_grid, "Write position using this grid.", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, {"prec", &opt_precision, "Precision of coordinates", "3", ARGTYPE_INT, ARG_NOMINMAX}, {"temp", &opt_temp, "Temperature unit [c=Celsius, f=Fahrenheit]", "c", ARGTYPE_STRING, ARG_NOMINMAX}, {"time", &opt_time_format, "Read/Write time format (i.e. HH:mm:ss xx)", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, @@ -137,6 +139,26 @@ static char *headers[] = { NULL }; +static char *grid_short_names[] = { + "ddd", + "dmm", + "dms", + "bng", + NULL +}; + +static char *grid_long_names[] = { /* starting at index !!! 3 !!! after inbuild lat/lon ... grids */ + "British National Grid", + NULL +}; + +#define GRID_IDX_LAT_LON_DDD 0 +#define GRID_IDX_LAT_LON_DMM 1 +#define GRID_IDX_LAT_LON_DMS 2 +#define GRID_IDX_BNG 3 + +#define GRID_IDX_MAX GRID_IDX_BNG + /* helpers */ static char * @@ -313,30 +335,59 @@ prework_wpt_cb(const waypoint *wpt) static void print_position(const waypoint *wpt) { - int deg; - double min; - char num[64]; - double lat, lon; + int valid; + double lat, lon, north, east; + char map[3]; + char latsig, lonsig; + double latmin, lonmin, latsec, lonsec; + int latint, lonint; convert_datum((waypoint *)wpt, 0, &lat, &lon); - deg = fabs(lat); - min = (double)60.0 * (fabs(lat) - deg); - snprintf(num, sizeof(num), "%0*.*f", precision + 3, precision, min); - if (atoi(num) == 60) { - deg++; - min = 0; - } - gbfprintf(fout, "%c%d %0*.*f ", lat < 0.0 ? 'S' : 'N', deg, precision + 3, precision, min); - - deg = fabs(lon); - min = (double)60.0 * (fabs(lon) - deg); - snprintf(num, sizeof(num), "%0*.*f", precision + 3, precision, min); - if (atoi(num) == 60) { - deg++; - min = 0; + /* ----------------------------------------------------------------------------*/ + /* the following code is from pretty_deg_format (util.c) */ + /* ----------------------------------------------------------------------------*/ + /* !ToDo! generate common code for calculating of degrees, minutes and seconds */ + /* ----------------------------------------------------------------------------*/ + + latsig = lat < 0 ? 'S':'N'; + lonsig = lon < 0 ? 'W':'E'; + latint = abs((int) lat); + lonint = abs((int) lon); + latmin = 60.0 * (fabs(lat) - latint); + lonmin = 60.0 * (fabs(lon) - lonint); + latsec = 60.0 * (latmin - floor(latmin)); + lonsec = 60.0 * (lonmin - floor(lonmin)); + + switch(grid_index) { + + case GRID_IDX_LAT_LON_DDD: + + gbfprintf(fout, "%c%0.*f %c%0.*f\t", + latsig, precision, fabs(lat), + lonsig, precision, fabs(lon)); + break; + + case GRID_IDX_LAT_LON_DMM: + + gbfprintf(fout, "%c%d %0*.*f %c%d %0*.*f\t", + latsig, latint, precision + 3, precision, latmin, + lonsig, lonint, precision + 3, precision, lonmin); + break; + + case GRID_IDX_LAT_LON_DMS: + + gbfprintf(fout, "%c%d %d %.*f %c%d %d %.*f\t", + latsig, latint, (int)latmin, precision, latsec, + lonsig, lonint, (int)lonmin, precision, lonsec); + break; + + case GRID_IDX_BNG: + valid = GPS_Math_WGS84_To_UKOSMap_M(wpt->latitude, wpt->longitude, &east, &north, map); + is_fatal(! valid, MYNAME ": Some (or all?) of the coordinates cannot be displayed using \"BNG\"."); + gbfprintf(fout, "%s %5.0f %5.0f", map, east, north); + break; } - gbfprintf(fout, "%c%d %0*.*f\t", lon < 0.0 ? 'W' : 'E', deg, precision + 3, precision, min); } static void @@ -691,10 +742,11 @@ track_disp_wpt_cb(const waypoint *wpt) static void garmin_txt_wr_init(const char *fname) { + char *grid_str; + memset(>xt_flags, 0, sizeof(gtxt_flags)); fout = gbfopen(fname, "wb", MYNAME); - grid_index = 1; gtxt_flags.metric = (toupper(*get_option_val(opt_dist, "m")) == 'M'); gtxt_flags.celsius = (toupper(*get_option_val(opt_temp, "c")) == 'C'); @@ -703,9 +755,47 @@ garmin_txt_wr_init(const char *fname) precision = atoi(opt_precision); is_fatal(precision < 0, MYNAME ": Invalid precision (%s)!", opt_precision); } + datum_str = get_option_val(opt_datum, NULL); - datum_index = GPS_Lookup_Datum_Index(datum_str); - is_fatal(datum_index < 0, MYNAME ": Invalid or unknown gps datum (%s)!", datum_str); + grid_str = get_option_val(opt_grid, NULL); + + grid_index = -1; + if (grid_str == NULL) { + grid_index = 1; /* default: dmm */ + } + else if (! sscanf(grid_str, "%d", &grid_index)) { + char *name; + int index; + + index = 0; + while ((name = grid_short_names[index])) { + if (case_ignore_strcmp(name, grid_str) == 0) { + grid_index = index; + break; + } + index++; + } + if (name == NULL) { /* look in "long names" */ + index = 0; + while ((name = grid_long_names[index])) { + if (case_ignore_strcmp(name, grid_str) == 0) break; + else index++; + } + is_fatal(name == NULL, + MYNAME ": Unsupported grid (%s). See GPSBabel help for supported grids.", grid_str); + grid_index = 3 + index; + } + } + else is_fatal(grid_index > GRID_IDX_MAX, MYNAME ": Grid index out of range (0..%d)!", GRID_IDX_MAX); + + switch(grid_index) { + case GRID_IDX_BNG: /* force datum to "Ord Srvy Grt Britn" */ + datum_index = GPS_Lookup_Datum_Index("OSGB36"); + break; + default: + datum_index = GPS_Lookup_Datum_Index(datum_str); + is_fatal(datum_index < 0, MYNAME ": Invalid or unknown gps datum (%s)!", datum_str); + } if (opt_utc != NULL) { if (case_ignore_strcmp(opt_utc, "utc") == 0) @@ -727,7 +817,22 @@ garmin_txt_wr_deinit(void) static void garmin_txt_write(void) { - cet_gbfprintf(fout, &cet_cs_vec_cp1252, "Grid\tLat/Lon hddd%cmm.mmm'\r\n", 0xB0); + switch(grid_index) { + case 0: + cet_gbfprintf(fout, &cet_cs_vec_cp1252, "Grid\tLat/Lon hddd.ddddd%c\r\n", 0xB0); + break; + case 1: + cet_gbfprintf(fout, &cet_cs_vec_cp1252, "Grid\tLat/Lon hddd%cmm.mmm'\r\n", 0xB0); + break; + case 2: + cet_gbfprintf(fout, &cet_cs_vec_cp1252, "Grid\tLat/Lon hddd%cmm'ss.s\"\r\n", 0xB0); + break; + case GRID_IDX_BNG: + cet_gbfprintf(fout, &cet_cs_vec_cp1252, "Grid\t%s\r\n", grid_long_names[0]); + datum_str = "Ord Srvy Grt Britn"; + break; + } + gbfprintf(fout, "Datum\t%s\r\n\r\n", datum_str); waypoints = 0; @@ -803,23 +908,31 @@ static void parse_position(const char *str, waypoint *wpt) { double lat, lon; - unsigned char lathemi, hemilon; + unsigned char lathemi, lonhemi; int deg_lat, deg_lon, min_lat, min_lon; + char map[3]; switch(grid_index) { - case 0: - sscanf(str, "%c%lf %c%lf", &lathemi, &lat, &hemilon, &lon); - break; - case 1: - sscanf(str, "%c%d %lf %c%d %lf", &lathemi, °_lat, &lat, &hemilon, °_lon, &lon); - lat = (double)deg_lat + (lat / (double)60); - lon = (double)deg_lon + (lon / (double)60); - break; - case 2: - sscanf(str, "%c%d %d %lf %c%d %d %lf", &lathemi, °_lat, &min_lat, &lat, &hemilon, °_lon, &min_lon, &lon); - lat = (double)deg_lat + ((double)min_lat / (double)60) + (lat / (double)3600.0); - lon = (double)deg_lon + ((double)min_lon / (double)60) + (lon / (double)3600.0); - break; + + case GRID_IDX_LAT_LON_DDD: + sscanf(str, "%c%lf %c%lf", &lathemi, &lat, &lonhemi, &lon); + break; + + case GRID_IDX_LAT_LON_DMM: + sscanf(str, "%c%d %lf %c%d %lf", &lathemi, °_lat, &lat, &lonhemi, °_lon, &lon); + lat = (double)deg_lat + (lat / (double)60); + lon = (double)deg_lon + (lon / (double)60); + break; + case GRID_IDX_LAT_LON_DMS: + sscanf(str, "%c%d %d %lf %c%d %d %lf", &lathemi, °_lat, &min_lat, &lat, &lonhemi, °_lon, &min_lon, &lon); + lat = (double)deg_lat + ((double)min_lat / (double)60) + (lat / (double)3600.0); + lon = (double)deg_lon + ((double)min_lon / (double)60) + (lon / (double)3600.0); + break; + + case GRID_IDX_BNG: + sscanf(str, "%2s %lf %lf", map, &lat, &lon); + lathemi = lonhemi = '\0'; + break; } if (lathemi == 'S') @@ -827,7 +940,7 @@ parse_position(const char *str, waypoint *wpt) else wpt->latitude = lat; - if (hemilon == 'W') + if (lonhemi == 'W') wpt->longitude = -lon; else wpt->longitude = lon; @@ -1025,11 +1138,25 @@ static void parse_grid(void) { char *str = csv_lineparse(NULL, "\t", "", 1); + grid_index = -1; + if (str != NULL) { - if (strstr(str, "dd.ddddd") != 0) grid_index = 0; - else if (strstr(str, "mm.mmm") != 0) grid_index = 1; - else if (strstr(str, "mm'ss.s") != 0) grid_index = 2; - else fatal(MYNAME ": Unsupported grid (%s)!\n", str); + if (strstr(str, "dd.ddddd") != 0) grid_index = GRID_IDX_LAT_LON_DDD; + else if (strstr(str, "mm.mmm") != 0) grid_index = GRID_IDX_LAT_LON_DMM; + else if (strstr(str, "mm'ss.s") != 0) grid_index = GRID_IDX_LAT_LON_DMS; + else { + char *name; + int index = 0; + + while ((name = grid_long_names[index])) { + if (case_ignore_strcmp(name, str) == 0) { + grid_index = GRID_IDX_BNG + index; + break; + } + index++; + } + } + is_fatal(grid_index < 0, MYNAME ": Unsupported grid (%s)!", str); } else fatal(MYNAME ": Missing grid headline!\n"); @@ -1196,7 +1323,7 @@ parse_track_waypoint(void) /***************************************************************/ static void -garmin_rd_init(const char *fname) +garmin_txt_rd_init(const char *fname) { memset(>xt_flags, 0, sizeof(gtxt_flags)); @@ -1210,7 +1337,7 @@ garmin_rd_init(const char *fname) } static void -garmin_rd_deinit(void) +garmin_txt_rd_deinit(void) { header_type h; @@ -1258,9 +1385,9 @@ garmin_txt_read(void) ff_vecs_t garmin_txt_vecs = { ff_type_file, FF_CAP_RW_ALL, - garmin_rd_init, + garmin_txt_rd_init, garmin_txt_wr_init, - garmin_rd_deinit, + garmin_txt_rd_deinit, garmin_txt_wr_deinit, garmin_txt_read, garmin_txt_write, diff --git a/gbfile.c b/gbfile.c index bc5505550..e86c491ec 100644 --- a/gbfile.c +++ b/gbfile.c @@ -1,8 +1,7 @@ /* Common GPSBabel file I/O API - - Copyright (C) 2006 Olaf Klein + Copyright (C) 2006 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -40,7 +39,7 @@ #endif #define MYNAME "gbfile" -#define NO_ZLIB MYNAME ": No zlib support\n." +#define NO_ZLIB MYNAME ": No zlib support.\n" /* About the ZLIB_INHIBITED stuff: * @@ -53,6 +52,10 @@ /* GPSBabel 'file' standard calls */ +/* + * gbfopen: (as xfopen) plus the name of the calling GPSBabel module (MYNAME) + */ + gbfile * gbfopen(const char *filename, const char *mode, const char *module) { @@ -67,6 +70,7 @@ gbfopen(const char *filename, const char *mode, const char *module) file->line = xstrdup(""); file->mode = 'r'; // default file->binary = (strchr(mode, 'b') != NULL); + file->back = -1; for (m = mode; *m; m++) { switch(tolower(*m)) { @@ -85,8 +89,12 @@ gbfopen(const char *filename, const char *mode, const char *module) /* Do we have a '.gz' extension in the filename ? */ len = strlen(file->name); if ((len > 3) && (case_ignore_strcmp(&file->name[len-3], ".gz") == 0)) { +#if !ZLIB_INHIBITED /* force gzipped files on output */ file->gzapi = 1; +#else + fatal(NO_ZLIB); +#endif } if (file->gzapi) { @@ -151,6 +159,10 @@ gbfopen_be(const char *filename, const char *mode, const char *module) return result; } +/* + * gbfclose: (as fclose) + */ + void gbfclose(gbfile *file) { @@ -173,6 +185,10 @@ gbfclose(gbfile *file) xfree(file); } +/* + * gbfgetc: (as fgetc) + */ + int gbfgetc(gbfile *file) { @@ -187,6 +203,10 @@ gbfgetc(gbfile *file) } } +/* + * gbfgets: (as fgets) + */ + char * gbfgets(char *buf, int len, gbfile *file) { @@ -212,7 +232,10 @@ gbfgets(char *buf, int len, gbfile *file) return (*result != '\0') ? result : NULL; } - +/* + * gbfread: (as fread) + */ + gbsize_t gbfread(void *buf, const gbsize_t size, const gbsize_t members, gbfile *file) { @@ -220,14 +243,29 @@ gbfread(void *buf, const gbsize_t size, const gbsize_t members, gbfile *file) if (file->gzapi) { #if !ZLIB_INHIBITED - int result; - result = gzread(file->handle.gz, buf, size * members) / size; + int result = 0; + char *target = buf; + int count = size * members; + + if (file->back != -1) { + *target++ = file->back; + count--; + result++; + file->back = -1; + } + result += gzread(file->handle.gz, target, count); + result /= size; if ((result < 0) || ((gbsize_t)result < members)) { int errnum; const char *errtxt; errtxt = gzerror(file->handle.gz, &errnum); + + /* Workaround for zlib bug: buffer error on empty files */ + if ((errnum == Z_BUF_ERROR) && (gztell(file->handle.gz) == 0)) { + return (gbsize_t) 0; + } if ((errnum != Z_STREAM_END) && (errnum != 0)) fatal("%s: zlib returned error %d ('%s')!\n", file->module, errnum, errtxt); @@ -250,6 +288,10 @@ gbfread(void *buf, const gbsize_t size, const gbsize_t members, gbfile *file) } } +/* + * gbfprintf: (as fprintf) + */ + int gbfprintf(gbfile *file, const char *format, ...) { @@ -287,6 +329,10 @@ gbfprintf(gbfile *file, const char *format, ...) return gbfwrite(file->buff, 1, len, file); } +/* + * gbfputc: (as fputc) + */ + int gbfputc(int c, gbfile *file) { @@ -297,12 +343,20 @@ gbfputc(int c, gbfile *file) return c; } +/* + * gbfputs: (as fputs) + */ + int gbfputs(const char *s, gbfile *file) { return gbfwrite(s, 1, strlen(s), file); } +/* + * gbfwrite: (as fwrite) + */ + int gbfwrite(const void *buf, const gbsize_t size, const gbsize_t members, gbfile *file) { @@ -332,6 +386,10 @@ gbfwrite(const void *buf, const gbsize_t size, const gbsize_t members, gbfile *f return result; } +/* + * gbfflush: (as fflush) + */ + int gbfflush(gbfile *file) { @@ -348,12 +406,18 @@ gbfflush(gbfile *file) } } +/* + * gbfclearerr: (as clearerr) + */ + void gbfclearerr(gbfile *file) { if (file->gzapi) { #if !ZLIB_INHIBITED gzclearerr(file->handle.gz); +#else + fatal(NO_ZLIB); #endif } else { @@ -361,6 +425,10 @@ gbfclearerr(gbfile *file) } } +/* + * gbferror: (as ferror) + */ + int gbferror(gbfile *file) { @@ -380,6 +448,10 @@ gbferror(gbfile *file) return errnum; } +/* + * gbfrewind: (as frewind) + */ + void gbfrewind(gbfile *file) { @@ -387,6 +459,10 @@ gbfrewind(gbfile *file) gbfclearerr(file); } +/* + * gbfseek: (as fseek) + */ + int gbfseek(gbfile *file, gbint32 offset, int whence) { @@ -397,12 +473,17 @@ gbfseek(gbfile *file, gbint32 offset, int whence) assert(whence != SEEK_END); #if !ZLIB_INHIBITED + if ((whence == SEEK_CUR) && (file->back != -1)) offset--; result = gzseek(file->handle.gz, offset, whence); + file->back = -1; #else result = 1; #endif - is_fatal(result < 0, - "%s: online compression not yet supported for this format!", file->module); + if (result < 0) { + if (strcmp(file->name, "-") == 0) + fatal("%s: This format cannot be used in piped commands!\n", file->module); + fatal("%s: online compression not yet supported for this format!", file->module); + } return 0; } @@ -411,12 +492,21 @@ gbfseek(gbfile *file, gbint32 offset, int whence) } } +/* + * gbftell: (as ftell) + */ + gbsize_t gbftell(gbfile *file) { if (file->gzapi) { #if !ZLIB_INHIBITED - return gztell(file->handle.gz); + gbsize_t result = gztell(file->handle.gz); + if (file->back != -1) { + file->back = -1; + result--; + } + return result; #else fatal(NO_ZLIB); return -1; @@ -427,12 +517,37 @@ gbftell(gbfile *file) } } +/* + * gbfeof: (as feof) + */ + int gbfeof(gbfile *file) { if (file->gzapi) { #if !ZLIB_INHIBITED - return gzeof(file->handle.gz); + int res; + + if (file->back != -1) return 0; + + res = gzeof(file->handle.gz); + if (!res) { + signed char test; + int len = gzread(file->handle.gz, &test, 1); + if (len == 1) { + /* No EOF, put the single byte back into stream */ + file->back = test; + } + else { + /* we are at the end of the file */ + if (global_opts.debug_level > 0) { + /* now gzeof() should return 1 */ + is_fatal(!gzeof(file->handle.gz), "zlib gzeof error!\n"); + } + res = 1; + } + } + return res; #else fatal(NO_ZLIB); return 0; @@ -443,13 +558,17 @@ gbfeof(gbfile *file) } } +/* + * gbfungetc: (as fungetc) + */ + int gbfungetc(const int c, gbfile *file) { int r = -1; if (file->gzapi) { #if !ZLIB_INHIBITED - r = gzungetc(c, file->handle.gz); + file->back = -1; #else fatal(NO_ZLIB); #endif @@ -462,25 +581,33 @@ gbfungetc(const int c, gbfile *file) /* GPSBabel 'file' enhancements */ +/* + * gbfgetint32: read a signed 32-bit integer from input stream + */ + gbint32 gbfgetint32(gbfile *file) { char buf[4]; - gbfread(buf, 1, sizeof(buf), file); - + gbfread(&buf, 1, sizeof(buf), file); + if (file->big_endian) return be_read32(buf); else return le_read32(buf); } +/* + * gbfgetint16: read a signed 16-bit integer from input stream + */ + gbint16 gbfgetint16(gbfile *file) { char buf[2]; - gbfread(buf, 1, sizeof(buf), file); + gbfread(&buf, 1, sizeof(buf), file); if (file->big_endian) return be_read16(buf); @@ -488,54 +615,63 @@ gbfgetint16(gbfile *file) return le_read16(buf); } +/* + * gbfgetdbl: read a double value (8 byte, double precision) from input stream + */ + double gbfgetdbl(gbfile *file) { char buf[8]; - gbfread(buf, 1, sizeof(buf), file); - return le_read_double(buf); + + gbfread(&buf, 1, sizeof(buf), file); + + return endian_read_double(buf, ! file->big_endian); } +/* + * gbfgetflt: read a float value (4 byte, single precision) from input stream + */ + float gbfgetflt(gbfile *file) { - union { - float f; - gbint32 i; - } x; + char buf[4]; - x.i = gbfgetint32(file); - return x.f; + gbfread(&buf, 1, sizeof(buf), file); + + return endian_read_float(buf, ! file->big_endian); } /* * gbfgetcstr: Reads a string from file until either a '\0' or eof. * The result is a temporary allocated entity: use it or free it! */ + char * gbfgetcstr(gbfile *file) { - int len, size; char *result; + int len = 0; + char *str = file->buff; - len = size = 0; - result = xstrdup(""); - - while (1) { + for (;;) { char c = gbfgetc(file); if ((c == 0) || (c == EOF)) break; - if (len == size) { - size += 32; - result = xrealloc(result, size + 1); + if (len == file->buffsz) { + file->buffsz += 64; + str = file->buff = xrealloc(file->buff, file->buffsz + 1); } - result[len] = c; + str[len] = c; len++; } - if ((len + 1) != size) - result = xrealloc(result, len + 1); + result = (char *) xmalloc(len + 1); + if (len > 0) + memcpy(result, str, len); + result[len] = '\0'; return result; } @@ -544,6 +680,7 @@ gbfgetcstr(gbfile *file) * gbfgetpstr: Reads a pascal string (first byte is length) from file. * The result is a temporary allocated entity: use it or free it! */ + char * gbfgetpstr(gbfile *file) { @@ -552,9 +689,9 @@ gbfgetpstr(gbfile *file) len = gbfgetc(file); result = xmalloc(len + 1); - - if (len > 0) + if (len > 0) { gbfread(result, 1, len, file); + } result[len] = '\0'; return result; @@ -564,15 +701,14 @@ gbfgetpstr(gbfile *file) * gbfgetstr: Reads a string from file (util any type of line-breaks or eof or error) * except xfree and free you can do all possible things with the result */ + char * gbfgetstr(gbfile *file) { - int len; + int len = 0; char *result = file->line; - len = file->linesz = 0; - - while (1) { + for (;;) { char c = gbfgetc(file); if ((c == EOF) || (c == 0x1A)) { @@ -583,24 +719,29 @@ gbfgetstr(gbfile *file) } else if (c == '\r') { c = gbfgetc(file); - if ((c != '\n') && (c != EOF)) gbfungetc(c, file); + if ((c != '\n') && (c != EOF)) + gbfungetc(c, file); break; } else if (c == '\n') { break; } if (len == file->linesz) { - file->linesz = len + 128; - result = file->line = xrealloc(file->line, len + 128 + 1); + file->linesz += 64; + result = file->line = xrealloc(file->line, file->linesz + 1); } result[len] = c; len++; } - result[len] = '\0'; // terminate resulting string + result[len] = '\0'; // terminate resulting string return result; } +/* + * gbfputint16: write a signed 16-bit integer value into output stream + */ + int gbfputint16(const gbint16 i, gbfile *file) { @@ -613,6 +754,10 @@ gbfputint16(const gbint16 i, gbfile *file) return gbfwrite(buf, 1, sizeof(buf), file); } +/* + * gbfputint32: write a signed 32-bit integer value into output stream + */ + int gbfputint32(const gbint32 i, gbfile *file) { @@ -625,43 +770,68 @@ gbfputint32(const gbint32 i, gbfile *file) return gbfwrite(buf, 1, sizeof(buf), file); } +/* + * gbfputdbl: write a double value (8 byte, double precision) into output stream + */ + int gbfputdbl(const double d, gbfile *file) { char buf[8]; - le_write_double(buf, d ); + + endian_write_double(buf, d, ! file->big_endian); return gbfwrite(buf, 1, sizeof(buf), file); } +/* + * gbfputflt: write a float value (4 byte, single precision) into output stream + */ + int gbfputflt(const float f, gbfile *file) { - union { - float f; - gbint32 i; } x; - - x.f = f; - return gbfputint32(x.i, file); + char buf[4]; + + endian_write_float(buf, f, ! file->big_endian); + return gbfwrite(buf, 1, sizeof(buf), file); } +/* + * gbfputcstr: write a NULL terminated string into a stream (!) including NULL + * return the number of written characters + */ + int gbfputcstr(const char *s, gbfile *file) { - return gbfwrite(s, 1, strlen(s) + 1, file); + int len; + + len = (s == NULL) ? 0 : strlen(s); + if (len > 0) { + return gbfwrite(s, 1, len + 1, file); + } else { + gbfputc(0, file); + return 1; + } } +/* + * gbfputcstr: write a pascal string into a stream + * return the number of written characters + */ + int gbfputpstr(const char *s, gbfile *file) { int len; - len = strlen(s); - if (len > 255) - len = 255; + len = (s == NULL) ? 0 : strlen(s); + if (len > 255) len = 255; /* the maximum size of a standard pascal string */ gbfputc(len, file); - gbfwrite(s, 1, len, file); - - return len + 1; + if (len > 0) { + gbfwrite(s, 1, len, file); + } + return (len + 1); } -/* Thats all, sorry */ +/* Thats all, sorry. */ diff --git a/gbfile.h b/gbfile.h index 596e9c2c5..7b1d28a7b 100644 --- a/gbfile.h +++ b/gbfile.h @@ -44,6 +44,7 @@ typedef struct gbfile_s { char *buff; /* static growing buffer, primary used by gbprintf */ int buffsz; char mode; + int back; unsigned char big_endian:1; unsigned char binary:1; unsigned char gzapi:1; @@ -81,6 +82,7 @@ double gbfgetdbl(gbfile *file); // read a double value float gbfgetflt(gbfile *file); // read a float value char *gbfgetstr(gbfile *file); // read until any type of line-breaks or EOF char *gbfgetpstr(gbfile *file); // read a pascal string +char *gbfgetcstr(gbfile *file); // read a null terminated string int gbfputint16(const gbint16 i, gbfile *file); #define gbfputuint16(a,b) gbfputint16((gbuint16)(a),(b)) diff --git a/gbser_posix.c b/gbser_posix.c index 6e398c13f..69f310b30 100644 --- a/gbser_posix.c +++ b/gbser_posix.c @@ -57,6 +57,7 @@ static speed_t mkspeed(unsigned br) { case 4800: return B4800; case 9600: return B9600; case 19200: return B19200; + case 38400: return B38400; #if defined B57600 case 57600: return B57600; #endif diff --git a/gbser_win.c b/gbser_win.c index 145969e36..c1a05269c 100644 --- a/gbser_win.c +++ b/gbser_win.c @@ -54,6 +54,7 @@ static DWORD mkspeed(unsigned br) { case 4800: return CBR_4800; case 9600: return CBR_9600; case 19200: return CBR_19200; + case 38400: return CBR_38400; case 57600: return CBR_57600; case 115200: return CBR_115200; default: diff --git a/gbtypes.h b/gbtypes.h index ad16fc88a..d247648af 100644 --- a/gbtypes.h +++ b/gbtypes.h @@ -52,5 +52,7 @@ typedef int16_t gbint16; #endif /* defined(_MSC_VER) */ typedef gbuint32 gbsize_t; +typedef unsigned char gbuint8; +typedef signed char gbint8; #endif /* gb_types_h_included */ diff --git a/gbversion.h b/gbversion.h new file mode 100644 index 000000000..76e859083 --- /dev/null +++ b/gbversion.h @@ -0,0 +1,8 @@ +/* + * gbversion.h is generated from gbversion.h.in which uses autoconf voodoo + * to get the version number from configure.in. + * + * Isn't simplification via automation grand? + */ +#define VERSION "1.3.3" + diff --git a/gbversion.h.in b/gbversion.h.in new file mode 100644 index 000000000..db491f99e --- /dev/null +++ b/gbversion.h.in @@ -0,0 +1,8 @@ +/* + * gbversion.h is generated from gbversion.h.in which uses autoconf voodoo + * to get the version number from configure.in. + * + * Isn't simplification via automation grand? + */ +#define VERSION "@GBMAJOR@.@GBMINOR@.@GBMICRO@@PACKAGE_RELEASE@" + diff --git a/gdb.c b/gdb.c index 460c78d28..e2c23825c 100644 --- a/gdb.c +++ b/gdb.c @@ -1,7 +1,7 @@ /* Garmin GPS Database Reader/Writer - Copyright (C) 2005,2006 Olaf Klein, o.b.klein@gpsbabel.org + Copyright (C) 2005-2007 Olaf Klein, o.b.klein@gpsbabel.org Mainly based on mapsource.c, Copyright (C) 2005 Robert Lipe, robertlipe@usa.net @@ -51,6 +51,8 @@ 2006/04/19: add url i/o to tracks and routes 2006/04/19: check for empty waypoint shortnames (paranioa) 2006/11/01: Use version of GPSBabel and date/time of gdb.c (managed by CVS) for watermark + 2007/01/23: add support for GDB version 3 + 2007/02/07: Add special code for unknown bytes in waypoints with class GE 8 (calculated points) */ #include @@ -62,6 +64,7 @@ #include "garmin_tables.h" #include "jeeps/gpsmath.h" #include "garmin_fs.h" +#include "cet_util.h" #define MYNAME "gdb" @@ -87,8 +90,8 @@ /* %%% local vars %%% */ -/* static char gdb_release[] = "$Revision: 1.43 $"; */ -static char gdb_release_date[] = "$Date: 2006/11/01 22:23:39 $"; +/* static char gdb_release[] = "$Revision: 1.48 $"; */ +static char gdb_release_date[] = "$Date: 2007/02/20 20:51:15 $"; static FILE *fin, *fout; static char *fin_name, *fout_name; @@ -359,6 +362,9 @@ gdb_read_file_header(void) case 'l': gdb_ver = 2; break; + case 'm': + gdb_ver = 3; + break; default: fatal(MYNAME ": Non supported GDB version!\n"); } @@ -495,21 +501,45 @@ gdb_read_wpt(const size_t fileofs, int *wptclass) GMSD_SET(depth, xdepth); } - gdb_fread(buff, 1); - gdb_fread(buff, 1); - - if (gdb_fread_flag(0)) - gdb_fread(buff, 3); - else + if (gdb_ver >= 3) { + int url_ct, unkn; + char *url = NULL; + + unkn = gdb_fread_le(&unkn, sizeof(unkn), 32, prefix, "unknown dword(x) since v3"); gdb_fread(buff, 2); - - do /* undocumented & unused string */ - { - gdb_fread(buff, 1); + + gdb_fread_str(xurl, sizeof(xurl)); /* what dagmar will say */ + + url_ct = gdb_fread_le(&url_ct, sizeof(url_ct), 32, prefix, "number of urls (since v3)"); + gdb_is_valid((url_ct >= 0), prefix, "Number of urls (since v3)"); + + while (url_ct > 0) { + url_ct--; + gdb_fread_str(xurl, sizeof(xurl)); /* URL list */ + if ((url == NULL) && (xurl[0] != '\0')) + url = xstrdup(xurl); /* keep only the first valid entry */ + } + if (url != NULL) { + strncpy(xurl, url, sizeof(xurl)); + xfree(url); + } } - while (buff[0] != 0); + else { /* gdb_ver <= 2 */ + gdb_fread(buff, 2); - gdb_fread_str(xurl, sizeof(xurl)); /* URL */ + if (gdb_fread_flag(0)) + gdb_fread(buff, 3); + else + gdb_fread(buff, 2); + + do /* undocumented & unused string */ + { + gdb_fread(buff, 1); + } + while (buff[0] != 0); + + gdb_fread_str(xurl, sizeof(xurl)); /* URL */ + } xcat = gdb_fread_le(&xcat, sizeof(xcat), 16, prefix, "category"); if (xcat != 0) GMSD_SET(category, xcat); @@ -519,28 +549,55 @@ gdb_read_wpt(const size_t fileofs, int *wptclass) GMSD_SET(temperature, xtemp); } - /* Here comes 1 .. 6 unknown bytes - !!! 6 only if class > 0 !!! - the field seems to be a time stamp */ - pos = ftell(fin); delta = fileofs - pos; - gdb_is_valid(delta > 0, prefix, "waypoint final"); - - if ((delta & 1) == 0) - { - gdb_fread(buff, 1); + gdb_is_valid((delta > 0), prefix, "waypoint final"); + + if (gdb_ver >= 3) { delta--; + if (gdb_fread_flag(1)) { + gdb_is_valid((delta >= 4), prefix, "No waypoint time (v3++)"); + gdb_fread_le(&xtime, sizeof(xtime), 32, prefix, "time"); + gdb_is_valid((xtime > 0), prefix, "Invalid time (v3++)"); + delta-=sizeof(xtime); + } + else + xtime = 0; + if (delta > 0) { /* skip over trailing unknown bytes */ + gdb_is_valid((delta <= sizeof(buff)), prefix, "Waypoint structure V3"); + gdb_fread(buff, delta); + } } - - xtime = 0; - if (gdb_fread_flag(1)) - { - gdb_is_valid((delta == 5), prefix, "Waypoint time"); - gdb_fread_le(&xtime, sizeof(xtime), 32, prefix, "time"); + else { /* gdb_ver <= 2 */ + + /* Here comes 1 .. 6 unknown bytes + !!! 6 only if class > 0 !!! + the field seems to be a time stamp */ + + if ((delta & 1) == 0) { + delta--; + gdb_fread(buff, 1); + if (buff[0] != '\0') + warning(MYNAME ": Invalid byte (0x%02x) at EOW'.\n", (unsigned char)buff[0]); + } + + xtime = 0; + + delta--; + if (gdb_fread_flag(1)) { + gdb_is_valid((delta == 4), prefix, "Waypoint time"); + gdb_fread_le(&xtime, sizeof(xtime), 32, prefix, "time"); + } + else if (delta > 0) { + gdb_is_valid((delta <= sizeof(buff)), prefix, "Waypoint structure"); + gdb_fread(buff, delta); + if (xclass < gt_waypt_class_map_point) { + warning(MYNAME ": Unhandled EOW. Please report!\n"); + fatal(MYNAME ": [class is 0x%02xh, %d bytes left, gdb version %d]\n", + xclass, (int)delta, gdb_ver); + } + } } - else - gdb_is_valid(delta==1, prefix, "No waypoint time"); *wptclass = xclass; @@ -643,6 +700,8 @@ gdb_read_route(void) #ifdef GDB_DEBUG gdb_print_buff(buff, 8, "Unknown bytes within rte_reed_loop"); #endif + if (gdb_ver >= 3) + gdb_fread(buff, 8); /* a second block of unknown bytes */ } /* The next thing is the unknown 0x03 0x00 .. 0x00 (18 bytes) */ @@ -658,13 +717,31 @@ gdb_read_route(void) gdb_fread(buff, 1); gdb_is_valid((buff[0] == 1), prefix3, "last seq.(1)"); - if (gdb_ver > 1) + if (gdb_ver >= 2) gdb_fread(buff, 8); /* Unknown 8 bytes since gdb v2 */ gdb_fread_str(xname, sizeof(xname)); - if (buff[0] != 0) + if (xname[0] != 0) route->rte_url = xstrdup(xname); + if (gdb_ver >= 3) { + + int url_ct, unkn; + + gdb_fread(buff, 1); /* Unknown byte since gdb v3 */ + gdb_fread_le(&url_ct, sizeof(url_ct), 32, prefix3, "number of urls (since v3)"); + while (url_ct > 0) { + url_ct--; + gdb_fread_str(xname, sizeof(xname)); + if (route->rte_url == NULL) + route->rte_url = xstrdup(xname); + } + gdb_fread_le(&unkn, sizeof(unkn), 32, prefix3, "unknown dword (since v3)"); + gdb_fread(buff, 1); /* Unknown byte since gdb v3 */ + gdb_fread_str(xname, sizeof(xname)); /* multi-line notes */ + if (xname[0] != '\0') + route->rte_desc = xstrdup(xname); + } wpt = gdb_create_rte_wpt(xwptname, xlat, xlon, xalt); if (wpt != NULL) route_add_wpt(route, wpt); @@ -744,8 +821,10 @@ gdb_read_route(void) if (gdb_fread_flag(1)) /* link min alt validity + alt */ gdb_fread(buff, 2 * sizeof(int)); - if (gdb_ver > 1) + if (gdb_ver >= 2) gdb_fread(buff, 8); /* unknown 8 bytes since gdb v2 */ + if (gdb_ver >= 3) + gdb_fread(buff, 2); /* unknown 8 bytes since gdb v3 */ } /* This should normally never happen; end of route is handled in main loop before this */ @@ -813,7 +892,7 @@ gdb_read_track(const size_t max_file_pos) wpt->latitude = GPS_Math_Semi_To_Deg(xlat); wpt->longitude = GPS_Math_Semi_To_Deg(xlon); wpt->creation_time = xtime; - wpt->centiseconds = 0; + wpt->microseconds = 0; wpt->altitude = xalt; wpt->depth = xdepth; @@ -822,9 +901,21 @@ gdb_read_track(const size_t max_file_pos) track_add_wpt(track, wpt); } - gdb_fread_str(xname, sizeof(xname)); - if (xname[0] != '\0') + if (gdb_ver >= 3) { + int url_ct; + + gdb_fread_le(&url_ct, sizeof(url_ct), 32, prefix, "number of urls (since v3)"); + while (url_ct > 0) { + url_ct--; + gdb_fread_str(xname, sizeof(xname)); + if ((track->rte_url == NULL) && (xname[0] != '\0')) + track->rte_url = xstrdup(xname); + } + } else { + gdb_fread_str(xname, sizeof(xname)); + if (xname[0] != '\0') track->rte_url = xstrdup(xname); + } return track; } @@ -882,7 +973,7 @@ gdb_read_data(void) if ((warnings & 1) == 0) { warnings |= 1; - warning(MYNAME "-%s: At least one incomplete waypoint read (%d byte(s) left).\n", prefix, delta); + warning(MYNAME "-%s: At least one incomplete waypoint (gdb v%d, %d byte(s) left).\n", prefix, gdb_ver, delta); } fseek(fin, curpos + reclen, SEEK_SET); } @@ -926,7 +1017,7 @@ gdb_read_data(void) if ((delta != reclen) && ((warnings & flag) == 0)) { warnings |= flag; - warning(MYNAME "-%s: At least one incomplete %s (gdb v%d.0, %d byte(s) left).\n", + warning(MYNAME "-%s: At least one incomplete %s (gdb v%d, %d byte(s) left).\n", prefix, (typ == 'R') ? "route" : "track", gdb_ver, delta); } fseek(fin, curpos + reclen, SEEK_SET); @@ -941,7 +1032,7 @@ gdb_read_data(void) case 'D': break; case 'L': break; case 'W': break; - default: warning(MYNAME "-%s: Found unknown record type \"%c\"!\n", prefix, typ); + default: warning(MYNAME "-%s: Found unknown record type \"%c\" (gdb v%d)!\n", prefix, typ, gdb_ver); } fseek(fin, curpos + reclen, SEEK_SET); } @@ -1244,7 +1335,7 @@ gdb_write_waypt(const waypoint *wpt, const int hidden) gdb_fwrite_alt(GMSD_GET(temperature, 0), 0); /* temperature */ - if (wpt->creation_time != 0) /* creation time */ + if (wpt->creation_time > 0) /* creation time */ { gdb_fwrite(&c1, 1); gdb_fwrite_int(wpt->creation_time); @@ -1449,7 +1540,7 @@ gdb_write_route(const route_head *route, const waypoint **list, const int count) gdb_fwrite_int(GPS_Math_Deg_To_Semi(minlon)); gdb_fwrite_alt(minalt, -unknown_alt); - if (gdb_ver > 1) + if (gdb_ver >= 2) gdb_fwrite(ffbuff, 8); } @@ -1475,7 +1566,7 @@ gdb_write_route(const route_head *route, const waypoint **list, const int count) gdb_fwrite_int(0); /* Zero interlink steps */ gdb_fwrite(&c1, 1); - if (gdb_ver > 1) + if (gdb_ver >= 2) gdb_fwrite(ffbuff, 8); gdb_fwrite_str(route->rte_url, -1); @@ -1548,7 +1639,7 @@ gdb_write_track(const route_head *track) gdb_fwrite_alt(wpt->altitude, unknown_alt); /* altitude */ - if (wpt->creation_time != 0) /* creation time */ + if (wpt->creation_time > 0) /* creation time */ { gdb_fwrite(&c1, 1); gdb_fwrite_int(wpt->creation_time); @@ -1671,6 +1762,9 @@ gdb_rd_init(const char *fname) fin_name = xstrdup(fname); fin = xfopen(fname, "rb", MYNAME); + gdb_read_file_header(); + + if (gdb_ver >= 3) cet_convert_init(CET_CHARSET_UTF8, 1); } static void @@ -1704,7 +1798,6 @@ gdb_wr_deinit(void) static void gdb_read(void) { - gdb_read_file_header(); gdb_read_data(); } @@ -1728,7 +1821,8 @@ ff_vecs_t gdb_vecs = { gdb_write, NULL, gdb_args, - CET_CHARSET_MS_ANSI, 1 /* CET-REVIEW */ + CET_CHARSET_MS_ANSI, 0 /* O.K.: changed to NON-FIXED */ + /* because of utf8 strings since GDB V3 */ }; /*******************************************************************************/ diff --git a/geo.c b/geo.c index 96f9d8d7b..9dbd84c9b 100644 --- a/geo.c +++ b/geo.c @@ -24,7 +24,7 @@ static char *nuke_placer; static waypoint *wpt_tmp; -static FILE *ofd; +static gbfile *ofd; static arglist_t geo_args[] = { @@ -68,8 +68,14 @@ xg_tag_mapping loc_map[] = { void wpt_s(const char *args, const char **unused) { -// wpt_tmp = waypt_new(); - wpt_tmp = xcalloc(sizeof(*wpt_tmp), 1); + wpt_tmp = waypt_new(); + /* + * 'geo' doesn't really have an 'unknown' and doesn't have any + * concept of alt. Unfortunately, we have many reference files + * that have leaked the 'unknown_alt' value into them, so we paper + * over that here. + */ + wpt_tmp->altitude = 0; } void wpt_e(const char *args, const char **unused) @@ -164,13 +170,13 @@ geo_rd_deinit(void) static void geo_wr_init(const char *fname) { - ofd = xfopen(fname, "w", MYNAME); + ofd = gbfopen(fname, "w", MYNAME); } static void geo_wr_deinit(void) { - fclose(ofd); + gbfclose(ofd); } static void @@ -178,34 +184,34 @@ geo_waypt_pr(const waypoint *waypointp) { char *tmp; - fprintf(ofd, "\n"); - fprintf(ofd, "", waypointp->shortname); - fprintf(ofd, "", waypointp->description); - fprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "", waypointp->shortname); + gbfprintf(ofd, "", waypointp->description); + gbfprintf(ofd, "\n"); - fprintf(ofd, "", + gbfprintf(ofd, "", waypointp->latitude, waypointp->longitude); - fprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); if (waypointp->icon_descr) { - fprintf(ofd, "%s\n", deficon ? deficon : waypointp->icon_descr); + gbfprintf(ofd, "%s\n", deficon ? deficon : waypointp->icon_descr); } if (waypointp->url) { tmp = xml_entitize(waypointp->url); - fprintf(ofd, "%s\n", + gbfprintf(ofd, "%s\n", tmp); xfree(tmp); } - fprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); } static void geo_write(void) { - fprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); waypt_disp_all(geo_waypt_pr); - fprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); } ff_vecs_t geo_vecs = { diff --git a/globals.c b/globals.c index 72e343d3a..f51201caa 100644 --- a/globals.c +++ b/globals.c @@ -21,6 +21,7 @@ #include "defs.h" +#include "gbversion.h" global_options global_opts; const char gpsbabel_version[] = VERSION; diff --git a/glogbook.c b/glogbook.c index 711d1225b..8a8d738c2 100644 --- a/glogbook.c +++ b/glogbook.c @@ -1,7 +1,7 @@ /* Access Garmin Logbook (Forerunner/Foretracker) data files. - Copyright (C) 2004 Robert Lipe, robertlipe@usa.net + Copyright (C) 2004, 2005, 2006, 2007 Robert Lipe, robertlipe@gpsbabel.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,7 +22,7 @@ #include "defs.h" #include "xmlgeneric.h" -static FILE *ofd; +static gbfile *ofd; static waypoint *wpt_tmp; static route_head *trk_head; @@ -75,52 +75,52 @@ glogbook_rd_deinit(void) static void glogbook_wr_init(const char *fname) { - ofd = xfopen(fname, "w", MYNAME); + ofd = gbfopen(fname, "w", MYNAME); } static void glogbook_wr_deinit(void) { - fclose(ofd); + gbfclose(ofd); } static void glogbook_waypt_pr(const waypoint *wpt) { - fprintf(ofd, " \n"); - fprintf(ofd, " \n"); - fprintf(ofd, " %.5f\n", wpt->latitude); - fprintf(ofd, " %.5f\n", wpt->longitude); + gbfprintf(ofd, " \n"); + gbfprintf(ofd, " \n"); + gbfprintf(ofd, " %.5f\n", wpt->latitude); + gbfprintf(ofd, " %.5f\n", wpt->longitude); if (wpt->altitude != unknown_alt) { - fprintf(ofd, " %.3f\n", wpt->altitude); + gbfprintf(ofd, " %.3f\n", wpt->altitude); } - fprintf(ofd, " \n"); - fprintf(ofd, " "); - xml_write_time(ofd, wpt->creation_time, "Time"); - fprintf(ofd, " \n"); + gbfprintf(ofd, " \n"); + gbfprintf(ofd, " "); + xml_write_time(ofd, wpt->creation_time, wpt->microseconds, "Time"); + gbfprintf(ofd, " \n"); } static void glogbook_hdr( const route_head *rte) { - fprintf(ofd, " \n"); + gbfprintf(ofd, " \n"); } static void glogbook_ftr(const route_head *rte) { - fprintf(ofd, " \n"); + gbfprintf(ofd, " \n"); } static void glogbook_write(void) { - fprintf(ofd, "\n"); - fprintf(ofd, "\n"); - fprintf(ofd, " \n"); + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); + gbfprintf(ofd, " \n"); track_disp_all(glogbook_hdr, glogbook_ftr, glogbook_waypt_pr); - fprintf(ofd, " \n"); - fprintf(ofd, "\n"); + gbfprintf(ofd, " \n"); + gbfprintf(ofd, "\n"); } void gl_trk_s(const char *args, const char **unused) @@ -147,7 +147,7 @@ void gl_trk_pnt_e(const char *args, const char **unused) void gl_trk_utc(const char *args, const char **unused) { - wpt_tmp->creation_time = xml_parse_time(args); + wpt_tmp->creation_time = xml_parse_time(args, &wpt_tmp->microseconds); } void gl_trk_lat(const char *args, const char **unused) diff --git a/google.c b/google.c index 6ff6a8f59..3c126ff62 100644 --- a/google.c +++ b/google.c @@ -345,6 +345,20 @@ google_read(void) } } xfree( script ); + script = NULL; + } + + /* + * 'Tis better to leak than crash when we are merging and + * don't see an 'end' in the first file. This feels a bit + * like plastering over a deeper problem... + * + */ + if ( encoded_points ) { + encoded_points = NULL; + } + if ( encoded_levels ) { + encoded_levels = NULL; } } #endif diff --git a/gpsbabel.html b/gpsbabel.html index af188eba0..83807aef4 100644 --- a/gpsbabel.html +++ b/gpsbabel.html @@ -1,23 +1,31 @@ -GPSBabel Documentation

GPSBabel Documentation


Table of Contents

Introduction
The Problem
The Solution
1. Getting it and Building it
2. Usage
Invocation
Advanced Usage
Route and Track Modes
Working with predefined options
Realtime tracking
Batch mode (command files)
3. The Formats
? Character Separated Values (xcsv)
All database fields on one tab-separated line (tabsep)
Brauniger IQ Series Barograph Download (baroiq)
Cambridge/Winpilot glider software (cambridge)
CarteSurTable data file (cst)
Cetus for Palm/OS (cetus)
CoastalExplorer XML (coastexp)
Comma separated values (csv)
CompeGPS data files (.wpt/.trk/.rte) (compegps)
CoPilot Flight Planner for Palm/OS (copilot)
cotoGPS for Palm/OS (coto)
Custom "Everything" Style (custom)
Dell Axim Navigation System (.gpb) file format (axim_gpb)
DeLorme .an1 (drawing) file (an1)
DeLorme GPL (gpl)
DeLorme Street Atlas Plus (saplus)
DeLorme Street Atlas Route (saroute)
DeLorme XMap HH Native .WPT (xmap)
DeLorme XMap/SAHH 2006 Native .TXT (xmap2006)
DeLorme XMat HH Street Atlas USA .WPT (PPC) (xmapwpt)
EasyGPS binary format (easygps)
FAI/IGC Flight Recorder Data Format (igc)
Franson GPSGate Simulation (gpssim)
Fugawi (fugawi)
Garmin 301 Custom position and heartrate (garmin301)
Garmin Logbook XML (glogbook)
Garmin MapSource - gdb (gdb)
Garmin MapSource - mps (mapsource)
Garmin MapSource - txt (tab delimited) (garmin_txt)
Garmin PCX5 (pcx)
Garmin POI database (garmin_poi)
Garmin serial/USB protocol (garmin)
Garmin Training Centerxml (gtrnctr)
Geocaching.com .loc (geo)
GeocachingDB for Palm/OS (gcdb)
GEOnet Names Server (GNS) (geonet)
GeoNiche .pdb (geoniche)
Google Earth (Keyhole) Markup Language (kml)
Google Maps XML (google)
GpilotS (gpilots)
GPS TrackMaker (gtm)
GPSBabel arc filter file (arc)
GpsDrive Format (gpsdrive)
GpsDrive Format for Tracks (gpsdrivetrack)
GPSman (gpsman)
GPSPilot Tracker for Palm/OS (gpspilot)
gpsutil (gpsutil)
GPX XML (gpx)
HikeTech (hiketech)
Holux (gm-100) .wpo Format (holux)
HSA Endeavour Navigator export File (hsandv)
HTML Output (html)
IGN Rando track files (ignrando)
Kartex 5 Track File (ktf2)
Kartex 5 Waypoint File (kwf2)
KuDaTa PsiTrex text (psitrex)
Lowrance USR (lowranceusr)
Magellan Explorist Geocaching (maggeo)
Magellan Mapsend (mapsend)
Magellan NAV Companion for Palm/OS (magnav)
Magellan SD files (as for eXplorist) (magellanx)
Magellan SD files (as for Meridian) (magellan)
Magellan serial protocol (magellan)
Map&Guide 'TourExchangeFormat' XML (tef)
Map&Guide to Palm/OS exported files (.pdb) (mag_pdb)
Mapopolis.com Mapconverter CSV (mapconverter)
MapTech Exchange Format (mxf)
Microsoft AutoRoute 2002 (pin/route reader) (msroute)
Microsoft Streets and Trips (pin/route reader) (msroute)
Microsoft Streets and Trips 2002-2006 (s_and_t)
Motorrad Routenplaner (Map&Guide) .bcr files (bcr)
MS PocketStreets 2002 Pushpin (psp)
National Geographic Topo .tpg (waypoints) (tpg)
National Geographic Topo 2.x .tpo (tpo2)
National Geographic Topo 3.x/4.x .tpo (tpo3)
Navicache.com XML (navicache)
Navigon Mobile Navigator .rte files (nmn4)
Navitrak DNA marker format (dna)
NetStumbler Summary File (text) (netstumbler)
NIMA/GNIS Geographic Names File (nima)
NMEA 0183 sentences (nmea)
OziExplorer (ozi)
PalmDoc Output (palmdoc)
PathAway Database for Palm/OS (pathaway)
Quovadis (quovadis)
See You flight analysis data (cup)
Sportsim track files (part of zipped .ssz files) (sportsim)
Suunto Trek Manager (STM) .sdf files (stmsdf)
Suunto Trek Manager (STM) WaypointPlus files (stmwpp)
Tab delimited fields useful for OpenOffice, Ploticus etc. (openoffice)
Textual Output (text)
TomTom POI file (tomtom)
TopoMapPro Places File (tmpro)
TrackLogs digital mapping (.trl) (dmtlog)
U.S. Census Bureau Tiger Mapping Service (tiger)
Universal csv with field structure in first line (unicsv)
Vcard Output (for iPod) (vcard)
Vito Navigator II tracks (vitosmt)
WiFiFoFum 2.0 for PocketPC XML (wfff)
Wintec WBT-100/200 Binary file format (wbt-bin)
Wintec WBT-100/200 GPS Download (wbt)
Yahoo Geocode API data (yahoo)
4. Data Filters
Include Only Points Inside Polygon (polygon)
Include Only Points Within Distance of Arc (arc)
Include Only Points Within Radius (radius)
Interpolate between trackpoints (interpolate)
Manipulate track lists (track)
Rearrange waypoints by resorting (sort)
Remove all waypoints, tracks, or routes (nuketypes)
Remove Duplicates (duplicate)
Remove Points Within Distance (position)
Remove unreliable points with high hdop or vdop (discard)
Reverse stops within routes (reverse)
Save and restore waypoint lists (stack)
Simplify routes (simplify)
Transformate waypoints into a route, tracks into routes, ... (transform)
A. Supported Datums
B. Garmin Icons
C. GPSBabel XCSV Style Files
Introduction
Style file overview
Internal Constants
Global Properties of the File
GPSBabel Behavior Directives
Defining the Layout of the File
Defining Fields Within the File
Examples
Miscellaneous Notes

List of Examples

3.1. Command showing garmin_txt output with all options
3.2. Sample BCR command with all options
3.3. Command showing conversion of a Wintec binary file to GPX
3.4. Command showing WBT-200 download and erase over Bluetooth on Mac OS X
4.1. Using the polygon filter
4.2. Using the polygon and arc filters to find points in or nearly in a +GPSBabel Documentation

GPSBabel Documentation


Table of Contents

Introduction
The Problem: Too many incompatible formats
The Solution
1. Getting it and Building it
2. Usage
Invocation
Suboptions
Advanced Usage
Route and Track Modes
Working with predefined options
Realtime tracking
Batch mode (command files)
3. The Formats
? Character Separated Values (xcsv)
Alan Map500 tracklogs (.trl) (alantrl)
Alan Map500 waypoints and routes (.wpr) (alanwpr)
All database fields on one tab-separated line (tabsep)
Brauniger IQ Series Barograph Download (baroiq)
Cambridge/Winpilot glider software (cambridge)
CarteSurTable data file (cst)
Cetus for Palm/OS (cetus)
CoastalExplorer XML (coastexp)
Comma separated values (csv)
CompeGPS data files (.wpt/.trk/.rte) (compegps)
CoPilot Flight Planner for Palm/OS (copilot)
cotoGPS for Palm/OS (coto)
Custom "Everything" Style (custom)
Dell Axim Navigation System (.gpb) file format (axim_gpb)
DeLorme .an1 (drawing) file (an1)
DeLorme GPL (gpl)
DeLorme Street Atlas Plus (saplus)
DeLorme Street Atlas Route (saroute)
DeLorme XMap HH Native .WPT (xmap)
DeLorme XMap/SAHH 2006 Native .TXT (xmap2006)
DeLorme XMat HH Street Atlas USA .WPT (PPC) (xmapwpt)
EasyGPS binary format (easygps)
FAI/IGC Flight Recorder Data Format (igc)
Franson GPSGate Simulation (gpssim)
Fugawi (fugawi)
Garmin 301 Custom position and heartrate (garmin301)
Garmin Logbook XML (glogbook)
Garmin MapSource - gdb (gdb)
Garmin MapSource - mps (mapsource)
Garmin MapSource - txt (tab delimited) (garmin_txt)
Garmin PCX5 (pcx)
Garmin POI database (garmin_poi)
Garmin serial/USB protocol (garmin)
Garmin Training Centerxml (gtrnctr)
Geocaching.com .loc (geo)
GeocachingDB for Palm/OS (gcdb)
GEOnet Names Server (GNS) (geonet)
GeoNiche .pdb (geoniche)
Google Earth (Keyhole) Markup Language (kml)
Google Maps XML (google)
GpilotS (gpilots)
GPS TrackMaker (gtm)
GPSBabel arc filter file (arc)
GpsDrive Format (gpsdrive)
GpsDrive Format for Tracks (gpsdrivetrack)
GPSman (gpsman)
GPSPilot Tracker for Palm/OS (gpspilot)
gpsutil (gpsutil)
GPX XML (gpx)
HikeTech (hiketech)
Holux (gm-100) .wpo Format (holux)
HSA Endeavour Navigator export File (hsandv)
HTML Output (html)
IGN Rando track files (ignrando)
Kartex 5 Track File (ktf2)
Kartex 5 Waypoint File (kwf2)
Kompass (DAV) Track (.tk) (kompass_tk)
Kompass (DAV) Waypoints (.wp) (kompass_wp)
KuDaTa PsiTrex text (psitrex)
Lowrance USR (lowranceusr)
Magellan Explorist Geocaching (maggeo)
Magellan Mapsend (mapsend)
Magellan NAV Companion for Palm/OS (magnav)
Magellan SD files (as for eXplorist) (magellanx)
Magellan SD files (as for Meridian) (magellan)
Magellan serial protocol (magellan)
Map&Guide 'TourExchangeFormat' XML (tef)
Map&Guide to Palm/OS exported files (.pdb) (mag_pdb)
Mapopolis.com Mapconverter CSV (mapconverter)
MapTech Exchange Format (mxf)
Microsoft AutoRoute 2002 (pin/route reader) (msroute)
Microsoft Streets and Trips (pin/route reader) (msroute)
Microsoft Streets and Trips 2002-2006 (s_and_t)
Motorrad Routenplaner (Map&Guide) .bcr files (bcr)
MS PocketStreets 2002 Pushpin (psp)
National Geographic Topo .tpg (waypoints) (tpg)
National Geographic Topo 2.x .tpo (tpo2)
National Geographic Topo 3.x/4.x .tpo (tpo3)
Navicache.com XML (navicache)
Navigon Mobile Navigator .rte files (nmn4)
Navitrak DNA marker format (dna)
NetStumbler Summary File (text) (netstumbler)
NIMA/GNIS Geographic Names File (nima)
NMEA 0183 sentences (nmea)
OziExplorer (ozi)
PalmDoc Output (palmdoc)
PathAway Database for Palm/OS (pathaway)
Quovadis (quovadis)
Raymarine Waypoint File (.rwf) (raymarine)
See You flight analysis data (cup)
Sportsim track files (part of zipped .ssz files) (sportsim)
Suunto Trek Manager (STM) .sdf files (stmsdf)
Suunto Trek Manager (STM) WaypointPlus files (stmwpp)
Tab delimited fields useful for OpenOffice, Ploticus etc. (openoffice)
Textual Output (text)
TomTom POI file (tomtom)
TopoMapPro Places File (tmpro)
TrackLogs digital mapping (.trl) (dmtlog)
U.S. Census Bureau Tiger Mapping Service (tiger)
Universal csv with field structure in first line (unicsv)
Vcard Output (for iPod) (vcard)
Vito Navigator II tracks (vitosmt)
WiFiFoFum 2.0 for PocketPC XML (wfff)
Wintec WBT-100/200 Binary file format (wbt-bin)
Wintec WBT-100/200 GPS Download (wbt)
Yahoo Geocode API data (yahoo)
4. Data Filters
Include Only Points Inside Polygon (polygon)
Include Only Points Within Distance of Arc (arc)
Include Only Points Within Radius (radius)
Interpolate between trackpoints (interpolate)
Manipulate track lists (track)
Rearrange waypoints by resorting (sort)
Remove all waypoints, tracks, or routes (nuketypes)
Remove Duplicates (duplicate)
Remove Points Within Distance (position)
Remove unreliable points with high hdop or vdop (discard)
Reverse stops within routes (reverse)
Save and restore waypoint lists (stack)
Simplify routes (simplify)
Transform waypoints into a route, tracks into routes, ... (transform)
A. Supported Datums
B. Garmin Icons
C. GPSBabel XCSV Style Files
Introduction
Style file overview
Internal Constants
Global Properties of the File
GPSBabel Behavior Directives
Defining the Layout of the File
Defining Fields Within the File
Examples
Miscellaneous Notes

List of Tables

3.1. Grid values for garmin_txt

Introduction

Table of Contents

The Problem
The Solution

The Problem

There are simply too many gratuitously different file formats +geocaches

4.13. Using the position filter to suppress close points
4.14. Using the discard filter
4.15. Converting a track to a sequence of waypoints
4.16. Converting a pile of waypoints to a GPX route
4.17. Converting a pile of waypoints to a GPX track
4.18. Convert a GPX track to GPX waypoints, tossing the original track

Introduction

The Problem: Too many incompatible formats

There are simply too many gratuitously different file formats to hold waypoint, track, and route information in various programs used by computers and GPS receivers. GPX defines a standard in XML to contain all the data, but there are too many programs that don't understand it yet and too much data that are in an alternate formats. -

The Solution

I needed to convert waypoints between a couple of formats, so I +

+Perhaps you have an Explorist 600 and your friend has a StreetPilot 2720. +You've collected a a list of your favorite locations as waypoints and you'd +like to be able to share them. Unfortunately, his copy of Garmin Mapsource +won't read data created by your copy of Magellan Directroute. What you need +is a program that converts data bewteen the two programs. +

+But GPSBabel actually does much more... +

The Solution

The original author of GPSBabel, Robert Lipe, needed to convert waypoints between a couple of formats, so he whipped up a converter and based it on an extensible foundation so -that it was easy to add new formats. Most file formats added so far -have taken under 200 lines of reasonable ISO C so they can be stamped -out pretty trivially. Formats that are ASCII text delimited in some -fixed way can be added with no programming at all via our 'style' -mechanism. -

Chapter 1. Getting it and Building it

+that it was easy to add new formats and made the program freely available. Many others have contributed to the program since then.

Most file formats added so far have taken under 200 + lines of reasonable ISO C so they can be stamped + out pretty trivially. Formats that are ASCII text delimited in some + fixed way can be added with no programming at all via our + style mechanism. +

Chapter 1. Getting it and Building it

GPSBabel is distributed "ready to run" on most common operating systems via the download page. @@ -33,15 +41,19 @@ ISO C89 compilers. It's been tested on UnixWare, OpenServer, OS/X, Linux, Solaris, and a variety of processors and compilers.

In most cases, the code is as simple to build as running: -

./configure && make

-

Expat +

./configure && make

Expat is strongly recommended for source builds as it is -required for reading all the XML formats such as GPX. +required for reading all the XML formats such as GPX. Fedora users +may need to 'yum install expat-devel'. Ubutnu users may need to +'apt-get install expat libexpat-dev'.

libusb is recommended for OS/X and Linux if you want to use a USB Garmin. +Fedora users may need to 'yum install expat-devel'. Ubutnu users may +need to 'apt-get install libusb-dev'.

There are additional flags that can be passed to configure to - customize your build of GPSBabel.

 ./configure --help

lists all the supported options, but additionally we have: -

+ customize your build of GPSBabel. +

./configure --help

+lists all the supported options, but additionally we have: --disable-shapefile Excludes the shapefile support.

--disable-pdb Excludes the Palm database support and all formats that rely on it. @@ -57,29 +69,32 @@ is recommended for OS/X and Linux if you want to use a USB Garmin. --without-libusb Disables use of libusb, even it's it's available.

--with-zlib=(included)|system|no By default, we use our own version of zlib. If you specify system the system zlib is used. A value of no (or --without-zlib) disables zlib. -

Chapter 2. Usage

Invocation

Invocation was meant to be flexible. Unfortunately, - that can sometimes lead to unwieldy command lines.

+

Chapter 2. Usage

Invocation

If you're using GPSBabel, you will need to know how to do at least two things: read data from a file, and write it to another file. There are four basic -commands you need to know to do those things: +options you need to know to do those things:

CommandMeaning
-i formatSet input format
-f filenameRead file
-o formatSet output format
-F filenameWrite output File

The format parameters in the above list refer to the names of formats or file types supported by GPSBabel. -

gpsbabel -? 

will always show you the supported file types. In this document, the +

gpsbabel -?

will always show you the supported file types. In this document, the various supported formats are listed in Chapter 3, The Formats. The name that you would use on the command line follows the format name in parentheses.

+Options are always processed in order from left to right. +In practical terms, this means that things you want to read should appear +in the command before things you want to write. +

The filename parameters specify the name of a file to be read or written.

To use this program, just tell it what you're reading, where to read it from, what you're writing, and what to write it to. For - example:

gpsbabel -i geo -f /tmp/geocaching.loc -o gpx -F /tmp/geocaching.gpx

tells it to read the file "/tmp/geocaching.loc" in geocaching.com + example:

gpsbabel -i geo -f /tmp/geocaching.loc -o gpx -F /tmp/geocaching.gpx

tells it to read the file "/tmp/geocaching.loc" in geocaching.com format and create a new file in GPX format.

This command will read from a Magellan unit attached to the first serial port on a Linux system (device names will vary on other OSes) and write them as a geocaching loc file. - The second command does the same on Microsoft Windows.

gpsbabel -i magellan -f /dev/ttyS0 -o geo -F mag.loc
gpsbabel -i magellan -f com1 -o geo -F mag.loc

Optionally, you may specify "-s" in any command line. This + The second command does the same on Microsoft Windows.

gpsbabel -i magellan -f /dev/ttyS0 -o geo -F mag.loc

gpsbabel -i magellan -f com1 -o geo -F mag.loc

Optionally, you may specify "-s" in any command line. This causes the program to ignore any "short" names that may be present in the source data format and synthesize one from the long name. This is particularly useful if you're writing to @@ -89,7 +104,28 @@ name of a file to be read or written. to my Magellan so my waypoints have "real" names instead of the 'GC1234' ones that are optimized for NMEA-only receivers. A geocacher with a Magellan receiver may thus find commands - like this useful.

 gpsbabel -s -i geo -f geocaching.loc -o magellan -F /dev/ttyS0  
 gpsbabel -s -i geo -f geocaching.loc -o magellan -F com1

Advanced Usage

Argument are processed in the order they appear on the command + like this useful.

gpsbabel -s -i geo -f geocaching.loc -o magellan -F /dev/ttyS0

gpsbabel -s -i geo -f geocaching.loc -o magellan -F com1

Suboptions

+ Many of the available format options in GPSBabel can themselves + take options. While we try to make all the formats do the most + sensible thing possible without any extra options, this allows + great power and flexibility in the operation of the program. +

+ Suboptions are comma separated and immediately follow the option + itself. The available suboptions are listed on the individual + format pages. We'll make an example from the section called “Google Earth (Keyhole) Markup Language (kml)”: +

gpsbabel -i gpx -f file.gpx -o kml,deficon="file://myicon.png",lines=0 -F one.kml -o kml -F two.kml

+ This command will read the GPX file file.gpx + and create two KML files. one.kml will + have the given icon and no lines between track and routepoints. + two.kml will be created with the defaults used + in the KML writer. +

+ Suboptions for the various formats allow you to change serial speeds, + pass arguments to filters, change the type of file written, override + icon defaults, and lots of other things. The suboptions for each + filetype are documented on the page in this document that describes + the option itself. +

Advanced Usage

Argument are processed in the order they appear on the command line and are translated internally into a pipeline that data flows through when executed. Normally one would:

read from one input
optionally apply filters
write into one output

but GPSBabel is flexible enough to allow more complicated operations such as reading from several files (potentially of @@ -98,23 +134,29 @@ merged data to multiple destinations.

The input file type remains unchanged until a new -i argument is seen. Files are read in the order they appear. So you could merge - three input files into one output file with:

gpsbabel -i geo -f 1.loc -f 2.loc -f 3.loc -o geo -F big.loc

You can merge files of different types:

gpsbabel  -i geo -f 1.loc -i gpx -f 2.gpx -i pcx 3.pcx \ 
--o gpsutil -F big.gps

You can write the same data in different output formats:

gpsbabel -i geo -f 1.loc -o gpx -F 1.gpx -o pcx 1.wpt

If you want to change the character set of input or/and + three input files into one output file with:

gpsbabel -i geo -f 1.loc -f 2.loc -f 3.loc -o geo -F big.loc

You can merge files of different types:

gpsbabel -i geo -f 1.loc -i gpx -f 2.gpx -i pcx 3.pcx +-o gpsutil -F big.gps

You can write the same data in different output formats:

gpsbabel -i geo -f 1.loc -o gpx -F 1.gpx -o pcx -F 1.wpt

If you want to change the character set of input or/and output side you can do this with the option -c <character set>. You can get a complete list of supported character sets with "gpsbabel -l". To change - the character set on both sides you should do this:

gpsbabel -i xcsv,style=foo.style -c latin1 -f foo  \
-	         -o xcsv,style=bar.style -c ms-ansi -F bar

Note, that some formats has a fixed character set and ignore this option.

Route and Track Modes

Most formats will make reasonable attempt to work + the character set on both sides you should do this:

gpsbabel -i xcsv,style=foo.style -c latin1 -f foo -o xcsv,style=bar.style -c ms-ansi -F bar

Note, that some formats has a fixed character set and ignore this option.

Route and Track Modes

Most formats supported by GPSBabel will make a reasonable attempt to work transparently with waypoints, tracks, and routes. Some - formats, like 'garmin' and 'magellan' require the -t flag to work with tracks and + formats, like garmin and magellan require the -t flag to work with tracks and -r to work with routes. -w is for waypoints, and is the default. So if you wanted to read all - data from your unit into a gpx file, you might use a command - like:

 gpsbabel -t -r -w -i magellan -f com1:  -o gpx -F backup.gpx

Tracks and routes are advanced features and don't try + data from a Magellan Meridian GPS receiver into a gpx file, you might use a command + like:

gpsbabel -t -r -w -i magellan -f com1: -o gpx -F backup.gpx

Tracks and routes are advanced features and don't try to handle every possible hazard that can be encountered during a conversion. If you're merging or converting files - of similar limitations, things work very well.

Tracks and routes will sometimes be converted to a + of similar limitations, things work very well.

Many of those hazards can be overcome with our filters + but there are often compromises to be made. For example, if you + have a GPX route that contains 150 turn points but you're sending + the route to a GPS receiver that supports only 30 turnpoints, something has + to go. One might use our 'simplify' filter to produce a route that + retained the 30 most mathematically significant turnpoints but that + may not really be the route you had in mind. +

Tracks and routes will sometimes be converted to a list of waypoints when necessary, f.i. when writing into one of the CSV formats. The inverse operation is not supported right now, so reading the converted track back from CSV will @@ -157,35 +199,32 @@ merged data to multiple destinations. There may be situations where predefined values are not useable (i.e. wrapper applications using GPSBabel in the background). The inifile mechanism can be disabled with an empty filename. -

gpsbabel -p "" -i gpx -f something.gpx -o tiger -F -

Realtime tracking

- Introduced in GPSBabel 1.3.1, we now have an experimental feature for realtime tracking via the new '-T' option. This reads position reports from selected formats and writes an output file when a position report is received. +

gpsbabel -p "" -i gpx -f something.gpx -o tiger -F -

Realtime tracking

+ Introduced in GPSBabel 1.3.1, we now have an experimental feature for realtime tracking via the new -T option. This reads position reports from selected formats and writes an output file when a position report is received.

As of this writing, Garmin's PVT protocol and NMEA are supported inputs and KML is supported on output. Additional formats may be added by interested parties later. -

-

gpsbabel -T -i garmin -f usb: -o kml -F xxx.kml

+

gpsbabel -T -i garmin -f usb: -o kml -F xxx.kml

Will read the USB-connected Garmin and rewrite 'xxx.kml' atomically, suitable for a self-refreshing network link in Google Earth.

Batch mode (command files)

In addition to reading arguments from the command line, GPSBabel can - read directions from batch (or command) files via the '-b' option. + read directions from batch (or command) files via the -b option.

These files are ideal for holding long command lines, long file lists, complex filters and so on. You can use all GPSBabel options and combinations when writing - such files. Nesting batch files by using the '-b' option within a batch file is supported. + such files. Nesting batch files by using the -b option within a batch file is supported.

Here is an example demonstrating segmenting a large command line by placing the input and filtering directives in a file called 'all_my_files'. -

gpsbabel -b all_my_files -o gdb -F all_my_tracks.gdb

-

+

gpsbabel -b all_my_files -o gdb -F all_my_tracks.gdb

'all_my_files' could look like this: -

-i gpx
-f saxony_in_summer_2004.gpx -f austria_2005.gpx
-i gdb
-f croatia_2006.gdb
-x nuketypes,waypoints,routes
-x track,pack,split,title="LOG # %Y%m%d"

Chapter 3. The Formats

Table of Contents

? Character Separated Values (xcsv)
All database fields on one tab-separated line (tabsep)
Brauniger IQ Series Barograph Download (baroiq)
Cambridge/Winpilot glider software (cambridge)
CarteSurTable data file (cst)
Cetus for Palm/OS (cetus)
CoastalExplorer XML (coastexp)
Comma separated values (csv)
CompeGPS data files (.wpt/.trk/.rte) (compegps)
CoPilot Flight Planner for Palm/OS (copilot)
cotoGPS for Palm/OS (coto)
Custom "Everything" Style (custom)
Dell Axim Navigation System (.gpb) file format (axim_gpb)
DeLorme .an1 (drawing) file (an1)
DeLorme GPL (gpl)
DeLorme Street Atlas Plus (saplus)
DeLorme Street Atlas Route (saroute)
DeLorme XMap HH Native .WPT (xmap)
DeLorme XMap/SAHH 2006 Native .TXT (xmap2006)
DeLorme XMat HH Street Atlas USA .WPT (PPC) (xmapwpt)
EasyGPS binary format (easygps)
FAI/IGC Flight Recorder Data Format (igc)
Franson GPSGate Simulation (gpssim)
Fugawi (fugawi)
Garmin 301 Custom position and heartrate (garmin301)
Garmin Logbook XML (glogbook)
Garmin MapSource - gdb (gdb)
Garmin MapSource - mps (mapsource)
Garmin MapSource - txt (tab delimited) (garmin_txt)
Garmin PCX5 (pcx)
Garmin POI database (garmin_poi)
Garmin serial/USB protocol (garmin)
Garmin Training Centerxml (gtrnctr)
Geocaching.com .loc (geo)
GeocachingDB for Palm/OS (gcdb)
GEOnet Names Server (GNS) (geonet)
GeoNiche .pdb (geoniche)
Google Earth (Keyhole) Markup Language (kml)
Google Maps XML (google)
GpilotS (gpilots)
GPS TrackMaker (gtm)
GPSBabel arc filter file (arc)
GpsDrive Format (gpsdrive)
GpsDrive Format for Tracks (gpsdrivetrack)
GPSman (gpsman)
GPSPilot Tracker for Palm/OS (gpspilot)
gpsutil (gpsutil)
GPX XML (gpx)
HikeTech (hiketech)
Holux (gm-100) .wpo Format (holux)
HSA Endeavour Navigator export File (hsandv)
HTML Output (html)
IGN Rando track files (ignrando)
Kartex 5 Track File (ktf2)
Kartex 5 Waypoint File (kwf2)
KuDaTa PsiTrex text (psitrex)
Lowrance USR (lowranceusr)
Magellan Explorist Geocaching (maggeo)
Magellan Mapsend (mapsend)
Magellan NAV Companion for Palm/OS (magnav)
Magellan SD files (as for eXplorist) (magellanx)
Magellan SD files (as for Meridian) (magellan)
Magellan serial protocol (magellan)
Map&Guide 'TourExchangeFormat' XML (tef)
Map&Guide to Palm/OS exported files (.pdb) (mag_pdb)
Mapopolis.com Mapconverter CSV (mapconverter)
MapTech Exchange Format (mxf)
Microsoft AutoRoute 2002 (pin/route reader) (msroute)
Microsoft Streets and Trips (pin/route reader) (msroute)
Microsoft Streets and Trips 2002-2006 (s_and_t)
Motorrad Routenplaner (Map&Guide) .bcr files (bcr)
MS PocketStreets 2002 Pushpin (psp)
National Geographic Topo .tpg (waypoints) (tpg)
National Geographic Topo 2.x .tpo (tpo2)
National Geographic Topo 3.x/4.x .tpo (tpo3)
Navicache.com XML (navicache)
Navigon Mobile Navigator .rte files (nmn4)
Navitrak DNA marker format (dna)
NetStumbler Summary File (text) (netstumbler)
NIMA/GNIS Geographic Names File (nima)
NMEA 0183 sentences (nmea)
OziExplorer (ozi)
PalmDoc Output (palmdoc)
PathAway Database for Palm/OS (pathaway)
Quovadis (quovadis)
See You flight analysis data (cup)
Sportsim track files (part of zipped .ssz files) (sportsim)
Suunto Trek Manager (STM) .sdf files (stmsdf)
Suunto Trek Manager (STM) WaypointPlus files (stmwpp)
Tab delimited fields useful for OpenOffice, Ploticus etc. (openoffice)
Textual Output (text)
TomTom POI file (tomtom)
TopoMapPro Places File (tmpro)
TrackLogs digital mapping (.trl) (dmtlog)
U.S. Census Bureau Tiger Mapping Service (tiger)
Universal csv with field structure in first line (unicsv)
Vcard Output (for iPod) (vcard)
Vito Navigator II tracks (vitosmt)
WiFiFoFum 2.0 for PocketPC XML (wfff)
Wintec WBT-100/200 Binary file format (wbt-bin)
Wintec WBT-100/200 GPS Download (wbt)
Yahoo Geocode API data (yahoo)

? Character Separated Values (xcsv)

+

-i gpx
-f saxony_in_summer_2004.gpx -f austria_2005.gpx
-i gdb
-f croatia_2006.gdb
-x nuketypes,waypoints,routes
-x track,pack,split,title="LOG # %Y%m%d"

Chapter 3. The Formats

Table of Contents

? Character Separated Values (xcsv)
Alan Map500 tracklogs (.trl) (alantrl)
Alan Map500 waypoints and routes (.wpr) (alanwpr)
All database fields on one tab-separated line (tabsep)
Brauniger IQ Series Barograph Download (baroiq)
Cambridge/Winpilot glider software (cambridge)
CarteSurTable data file (cst)
Cetus for Palm/OS (cetus)
CoastalExplorer XML (coastexp)
Comma separated values (csv)
CompeGPS data files (.wpt/.trk/.rte) (compegps)
CoPilot Flight Planner for Palm/OS (copilot)
cotoGPS for Palm/OS (coto)
Custom "Everything" Style (custom)
Dell Axim Navigation System (.gpb) file format (axim_gpb)
DeLorme .an1 (drawing) file (an1)
DeLorme GPL (gpl)
DeLorme Street Atlas Plus (saplus)
DeLorme Street Atlas Route (saroute)
DeLorme XMap HH Native .WPT (xmap)
DeLorme XMap/SAHH 2006 Native .TXT (xmap2006)
DeLorme XMat HH Street Atlas USA .WPT (PPC) (xmapwpt)
EasyGPS binary format (easygps)
FAI/IGC Flight Recorder Data Format (igc)
Franson GPSGate Simulation (gpssim)
Fugawi (fugawi)
Garmin 301 Custom position and heartrate (garmin301)
Garmin Logbook XML (glogbook)
Garmin MapSource - gdb (gdb)
Garmin MapSource - mps (mapsource)
Garmin MapSource - txt (tab delimited) (garmin_txt)
Garmin PCX5 (pcx)
Garmin POI database (garmin_poi)
Garmin serial/USB protocol (garmin)
Garmin Training Centerxml (gtrnctr)
Geocaching.com .loc (geo)
GeocachingDB for Palm/OS (gcdb)
GEOnet Names Server (GNS) (geonet)
GeoNiche .pdb (geoniche)
Google Earth (Keyhole) Markup Language (kml)
Google Maps XML (google)
GpilotS (gpilots)
GPS TrackMaker (gtm)
GPSBabel arc filter file (arc)
GpsDrive Format (gpsdrive)
GpsDrive Format for Tracks (gpsdrivetrack)
GPSman (gpsman)
GPSPilot Tracker for Palm/OS (gpspilot)
gpsutil (gpsutil)
GPX XML (gpx)
HikeTech (hiketech)
Holux (gm-100) .wpo Format (holux)
HSA Endeavour Navigator export File (hsandv)
HTML Output (html)
IGN Rando track files (ignrando)
Kartex 5 Track File (ktf2)
Kartex 5 Waypoint File (kwf2)
Kompass (DAV) Track (.tk) (kompass_tk)
Kompass (DAV) Waypoints (.wp) (kompass_wp)
KuDaTa PsiTrex text (psitrex)
Lowrance USR (lowranceusr)
Magellan Explorist Geocaching (maggeo)
Magellan Mapsend (mapsend)
Magellan NAV Companion for Palm/OS (magnav)
Magellan SD files (as for eXplorist) (magellanx)
Magellan SD files (as for Meridian) (magellan)
Magellan serial protocol (magellan)
Map&Guide 'TourExchangeFormat' XML (tef)
Map&Guide to Palm/OS exported files (.pdb) (mag_pdb)
Mapopolis.com Mapconverter CSV (mapconverter)
MapTech Exchange Format (mxf)
Microsoft AutoRoute 2002 (pin/route reader) (msroute)
Microsoft Streets and Trips (pin/route reader) (msroute)
Microsoft Streets and Trips 2002-2006 (s_and_t)
Motorrad Routenplaner (Map&Guide) .bcr files (bcr)
MS PocketStreets 2002 Pushpin (psp)
National Geographic Topo .tpg (waypoints) (tpg)
National Geographic Topo 2.x .tpo (tpo2)
National Geographic Topo 3.x/4.x .tpo (tpo3)
Navicache.com XML (navicache)
Navigon Mobile Navigator .rte files (nmn4)
Navitrak DNA marker format (dna)
NetStumbler Summary File (text) (netstumbler)
NIMA/GNIS Geographic Names File (nima)
NMEA 0183 sentences (nmea)
OziExplorer (ozi)
PalmDoc Output (palmdoc)
PathAway Database for Palm/OS (pathaway)
Quovadis (quovadis)
Raymarine Waypoint File (.rwf) (raymarine)
See You flight analysis data (cup)
Sportsim track files (part of zipped .ssz files) (sportsim)
Suunto Trek Manager (STM) .sdf files (stmsdf)
Suunto Trek Manager (STM) WaypointPlus files (stmwpp)
Tab delimited fields useful for OpenOffice, Ploticus etc. (openoffice)
Textual Output (text)
TomTom POI file (tomtom)
TopoMapPro Places File (tmpro)
TrackLogs digital mapping (.trl) (dmtlog)
U.S. Census Bureau Tiger Mapping Service (tiger)
Universal csv with field structure in first line (unicsv)
Vcard Output (for iPod) (vcard)
Vito Navigator II tracks (vitosmt)
WiFiFoFum 2.0 for PocketPC XML (wfff)
Wintec WBT-100/200 Binary file format (wbt-bin)
Wintec WBT-100/200 GPS Download (wbt)
Yahoo Geocode API data (yahoo)

? Character Separated Values (xcsv)

This format can... -

  • +

    • read and write waypoints

    -

    This format is a very flexible module that can be used to read or write nearly any plain-text record-based waypoint file. This flexibility is achieved by combining this format with "style" files that describe the @@ -196,7 +235,7 @@ machinery. Each of those formats takes the same options as the xcsv format, with the obvious exception of the style option. Those formats are all based on style files that can be found in the "style" directory in the GPSBabel source distribution. -

    style option

    +

    style option

    Full path to XCSV style file.

    This option specifies the style file that defines the records to be read on @@ -205,53 +244,108 @@ built-in xcsv-based styles; they have prebuilt style definitions.

    For information on the format of xcsv style files, see Appendix C, GPSBabel XCSV Style Files. -

    snlen option

    +

    snlen option

    Max synthesized shortname length.

    This option specifies the maximum allowable length for a short name on output. This option overrides the style file.

    Valid values for this option are 0 (off) and 1 (on). -

    snwhite option

    +

    snwhite option

    Allow whitespace synth. shortnames.

    When this option is specified, GPSBabel will allow whitespace (spaces or tabs) in generated short names. This option overrides the style file.

    Valid values for this option are 0 (off) and 1 (on). -

    snupper option

    +

    snupper option

    UPPERCASE synth. shortnames.

    When this option is specified, GPSBabel will make all short names contain only UPPERCASE characters. This option overrides the style file.

    Valid values for this option are 0 (off) and 1 (on). -

    snunique option

    +

    snunique option

    Make synth. shortnames unique.

    When this option is specified, GPSBabel will ensure that all short names are unique within the output file. This option overrides the style file.

    Valid values for this option are 0 (off) and 1 (on). -

    urlbase option

    +

    urlbase option

    Basename prepended to URL on output.

    This option specifies the base name to prepend to a URL on output. This might be useful if an input file contains URLs in a relative format and you need them to be in an absolute format. -

    prefer_shortnames option

    +

    prefer_shortnames option

    Use shortname instead of description.

    This option causes GPSBabel to use the short name of the waypoint instead of the description. This overrides the style file.

    Valid values for this option are 0 (off) and 1 (on). -

    All database fields on one tab-separated line (tabsep)

    +

    datum option

    + GPS datum (def. WGS 84). +

    +This option specifies the GPS datum to be used on read or write. Valid values for this +option are listed in Appendix A, Supported Datums. +

Alan Map500 tracklogs (.trl) (alantrl)

This format can... -

  • +

    • + read and write tracks +

    +GPSBabel supports .wpr and .trl files for Alan Map500 devices running operating +system versions 2.xx. +

    +.trl contain files tracklogs. If you use a CF-Card based +operating system, tracklog files must have a .TRL extension when +copied to the CF-Card. The default filename is TEMP_TRK.TRL. +Only one .TRL file may be present. +

    +Alan's operating system 3.0 for Map500 is not supported yet. +At the time of this writing, OS3 is still beta. +Documentation on the new dataformats is sparse. +

    +The Alan Map500 handheld GPSr is identical to the Holux GM101. +This GPSBabel module has only been tested against the Alan Map500. +Still, if you use a GM101, GPSBabel will probably be able to convert +your waypoints, routes and tracklogs. +

    +For more information on the Alan Map500 visit +Alan Germany. There is very informative forum, too. The forum language is German but posts in English will be answered, too. +

Alan Map500 waypoints and routes (.wpr) (alanwpr)

+ This format can... +

  • + read and write waypoints +

  • + read and write routes +

+GPSBabel supports .wpr and .trl files for Alan Map500 devices running operating +system versions 2.xx. +

+.wpr files contain waypoints and routes. If you use a CF-Card based +operating system, waypoint files must have a .WPR extension when +copied to the CF-Card. The default filename is TEMPWPRT.WPR. +Only one .WPR file may be present. +

+Alan's operating system 3.0 for Map500 is not supported yet. +At the time of this writing, OS3 is still beta. +Documentation on the new dataformats is sparse. +

+The Alan Map500 handheld GPSr is identical to the Holux GM101. +This GPSBabel module has only been tested against the Alan Map500. +Still, if you use a GM101, GPSBabel will probably be able to convert +your waypoints, routes and tracklogs. +

+For more information on the Alan Map500 visit +Alan Germany. There is very informative forum, too. Forum language is German but posts in English will be answered, +too. +

All database fields on one tab-separated line (tabsep)

+ This format can... +

  • read and write waypoints

-

This format is derived from the xcsv format, so it has all of the same options as that format.

@@ -263,56 +357,54 @@ in sync with the documentation at

Brauniger IQ Series Barograph Download (baroiq)

+

Brauniger IQ Series Barograph Download (baroiq)

This format can... -

  • +

    • read and write waypoints -

    • +

    • read and write tracks -

    • +

    • read and write routes -

    -

    Serial download protocol for the Brauniger IQ series of +

Serial download protocol for the Brauniger IQ series of barograph recording flight instruments. This format creates a track of altitude vs time which can be merged with a GPS track -of the same flight to create a three dimensional IGC file.

Cambridge/Winpilot glider software (cambridge)

+of the same flight to create a three dimensional IGC file.

Cambridge/Winpilot glider software (cambridge)

This format can... -

  • +

    • read and write waypoints

    -

    This format is derived from the xcsv format, so it has all of the same options as that format. -

    Support for Cambridge/Winpilot flight analysis and planning software for - glider pilots.

CarteSurTable data file (cst)

+

Support for +Cambridge +and Winpilot + flight analysis and planning software for glider pilots.

CarteSurTable data file (cst)

This format can... -

  • +

    • read waypoints -

    • +

    • read tracks -

    • +

    • read routes -

    -

    With this format we can read CarteSurTable data files. -CarteSurTable is a shareware program widely used in France. The data +

With this format we can read CarteSurTable data files. + CarteSurTable is a shareware program widely used in France. The data inside have to be seen as a mixture of a waypoints list, one route and -several tracks. phgiraud.free.fr -

Cetus for Palm/OS (cetus)

+several tracks. +

Cetus for Palm/OS (cetus)

This format can... -

  • +

    • read and write waypoints -

    • +

    • read tracks -

    -

    Cetus GPS www.cetusgps.dk is a program for +

Cetus GPS is a program for Palm/OS. Working with Ron Parker and Kjeld Jensen, we can now read -and write files for that program.

dbname option

+and write files for that program.

dbname option

Database name.

This option specifies the database name for the output file. This name is not the same thing as the file name on your computer; this is the name that appears in the file browser on your handheld. -

appendicon option

+

appendicon option

Append icon_descr to description.

This option will add the icon description to the end of the waypoint @@ -320,41 +412,45 @@ description on output. This can be useful if the icon is used to convey important information about the waypoint. For example, the icon might be "found geocache" or "unfound geocache"; it might be useful to know that when looking at a list of icons in Cetus. -

CoastalExplorer XML (coastexp)

+

CoastalExplorer XML (coastexp)

This format can... -

  • +

    • read and write waypoints -

    • +

    • read and write routes -

    -

    This is the format used by CoastalExplorer (tm). The +

This is the format used by CoastalExplorer™. The format is XML with items uniquely identified by Windows-style UUIDs. http://www.rosepointnav.com -

Comma separated values (csv)

+

Comma separated values (csv)

This format can... -

  • +

    • read and write waypoints

    -

    This format is derived from the xcsv format, so it has all of the same options as that format.

    There are a billion variants of Comma Separated Value -data. This is the one that makes Delorme S&A Deluxe 9 happy. It's +data. This is the one that makes Delorme S&A Deluxe 9™ happy. It's also a very simple program and useful for many other programs like -spreadsheets.

    CSV is also the correct format for Lowrance MapCreate, +spreadsheets.

    CSV is also the correct format for + Lowrance MapCreate™, their commercial mapping program, or GDM6 (their free waypoint manager) for iFinder which is available at lowrance.com -

CompeGPS data files (.wpt/.trk/.rte) (compegps)

+

+ On write, this format writes simple "latitude, longitude" pairs, but +on read it will read anything supported by our human readable definition. +

+ For something-separated data that has headers identifying the various + fields, see our universal csv format. +

CompeGPS data files (.wpt/.trk/.rte) (compegps)

This format can... -

  • +

    • read and write waypoints -

    • +

    • read and write tracks -

    • +

    • read and write routes

    -

    -These data files are "character" separated text files like +CompeGPS™ data files are "character" separated text files like the pcx format. "Character" means special data lines can have their own separator.

    @@ -363,11 +459,11 @@ supported import/export format for waypoints, routes and tracks.

    For more information please have a look at http://www.compegps.com -

    deficon option

    +

    deficon option

    Default icon name.

    This option specifies the default icon name on output. -

    index option

    +

    index option

    Index of route/track to write (if more the one in source).

    Because this format supports only one route or track, this option may be used @@ -375,36 +471,36 @@ on output to select a single route or track from a collection of routes and tracks read from a more expressive format. If you have, say, a gpx file that contains two routes, you may use this option to write them one at a time to individual files. -

    gpsbabel -i gpx -f routes.gpx -o compegps,index=1 -F route1.txt -o compegps,index=2 -F route2.txt

    radius option

    +

    gpsbabel -i gpx -f routes.gpx -o compegps,index=1 -F route1.txt -o compegps,index=2 -F route2.txt

    radius option

    Give points (waypoints/route points) a default radius (proximity).

    This option specifies the default proximity for waypoints and route points. -

    snlen option

    +

    snlen option

    Length of generated shortnames (default 16).

    This option specifies the default length for short names generated on output. The default length is 16. -

    CoPilot Flight Planner for Palm/OS (copilot)

    +

CoPilot Flight Planner for Palm/OS (copilot)

This format can... -

  • +

    • read and write waypoints -

    -

    This code is mostly intended to convert CoPilot Flight -Planner for Palmd/OS atabases into other formats. You probably should +

This code is mostly intended to convert CoPilot Flight +Planner for Palm/OS" databases into other formats. You probably should not use this to write CoPilot databases, although the code is there, -because GPSBabel doesn't convert magnetic declination values.

Questions, bug reports, etc, to ptomblin at +because GPSBabel doesn't convert magnetic declination values.

This version now reads all CoPilot file versions up to 4, but only +writes version 4 files. If you have a need for a version flag, please let +me know.

Questions, bug reports, etc, to ptomblin at xcski.com

http://xcski.com/~ptomblin/CoPilot/ and http://navaid.com/CoPilot -

cotoGPS for Palm/OS (coto)

+

cotoGPS for Palm/OS (coto)

This format can... -

  • +

    • read and write waypoints -

    • +

    • read tracks -

    -

    -This format supports cotoGPS™, a Palm GPS program. +

+This format supports cotoGPS™, a Palm™ GPS program. It can read both track and marker (waypoint) files. It is currently unable to write track files, so only marker files can be written. The marker categories are written to and read from the icon description. The 'Not @@ -418,17 +514,16 @@ of the cotoGPS track format to the notes field. Contributed by Tobias Minich.

cotoGPS -

zerocat option

+

zerocat option

Name of the 'unassigned' category.

This option specifies a name for the "Not Assigned" category in the Palm database. The default is "Not Assigned". -

Custom "Everything" Style (custom)

+

Custom "Everything" Style (custom)

This format can... -

  • +

    • read and write waypoints

    -

    This format is derived from the xcsv format, so it has all of the same options as that format.

    @@ -438,45 +533,43 @@ for debugging purposes when developing a new format module for GPSBabel. To understand the contents of this file, look at the style/custom.style file in the GPSBabel source distribution as well as Appendix C, GPSBabel XCSV Style Files. -

Dell Axim Navigation System (.gpb) file format (axim_gpb)

+

Dell Axim Navigation System (.gpb) file format (axim_gpb)

This format can... -

  • +

    • read tracks

    -

    This format reads the binary (.gpb) track logs recorded on - Dell Axim Navigation Systems. + Dell Axim Navigation Systems.

    This is a read-only format for now as the format was reverse engineered and there are many unknown bytes. We can successfully extract the common GPS data. -

DeLorme .an1 (drawing) file (an1)

+

DeLorme .an1 (drawing) file (an1)

This format can... -

  • +

    • read and write waypoints -

    • - read and write tracks -

    • +

    • + write tracks +

    • read and write routes -

    -

    -This format supports the DeLorme ".an1" drawing file format. It can +

+This format supports the DeLorme ".an1" drawing file format. It can currently be used to either read or write drawing files. If you use this format to create drawing files with routes or waypoints from another source, by default it will create "Red Flag" symbols for waypoints, and thick red lines for routes or tracks. It is possible to merge two drawing layers by doing something like this: -

gpsbabel -i an1 -f one.an1 -f two.an1 -o an1 -F merged.an1

+

gpsbabel -i an1 -f one.an1 -f two.an1 -o an1 -F merged.an1

In this case, the merged data will contain all of the properties of the original data. -

type option

+

type option

Type of .an1 file.

This option specifies the type of the drawing layer to be created. The supported values are "drawing", "road", "trail", "waypoint", or "track". If you do not specify a type, the default will be either the type of the previous an1 file or "drawing" if there is no previous file. This lets you merge, for example, two road layers -without having to specify "type=road" for the output.

road option

+without having to specify "type=road" for the output.

road option

Road type changes.

If you are creating a road layer, you may use the "road" option, which @@ -489,7 +582,7 @@ GPSBabel defaults to creating editable roads. These are routed just like local roads, but may be edited with the drawing tools in Street Atlas.

This option has a special format that is best demonstrated by example: -

"road=I-599!limited!Beecher St.!major" 

+

 "road=I-599!limited!Beecher St.!major" 

This option will cause any road named "I-599" to become a limited-access highway and any road named "Beecher St." to become a major connector. Note that roads that have had their types changed in this way are not editable @@ -502,14 +595,14 @@ There is a tutorial on how to create an onramp for a limited access highway in Street Atlas USA using GPSBabel. -

nogc option

+

nogc option

Do not add geocache data to description.

If your original data contains geocaching-specific information such as difficulty and terrain, GPSBabel will automatically include that information in the waypoint descriptions in the generated drawing file. If you do not want that, specify the "nogc" option on the command line: -

gpsbabel -i gpx -f 12345.gpx -o an1,nogc -F 12345.an1

deficon option

+

gpsbabel -i gpx -f 12345.gpx -o an1,nogc -F 12345.an1

deficon option

Symbol to use for point data.

This option allows you to specify which symbol to use for points that @@ -517,12 +610,12 @@ don't have a symbol already. It defaults to "Red Flag" but it accepts any symbol name you can put in a DeLorme export file. To find the name of a specific symbol in Street Atlas, let the mouse pointer hover over it for a few seconds and the name will be displayed. -

color option

+

color option

Color for lines or mapnotes.

This option allows you to specify the color for line or mapnote data. It accepts color names of the form "#FF0000" (red) or any of the color names from the Cascading Style Sheets (CSS) -specification.

zoom option

+specification.

zoom option

Zoom level to reduce points.

This option specifies at what zoom level Street Atlas will begin showing @@ -530,7 +623,7 @@ reduced versions of your symbols. The default is 10. Setting zoom to 0 will disable this feature. Setting it to anything but the default will override the zoom level specified on any waypoints that were read from an existing an1 file; this is by design. -

wpt_type option

+

wpt_type option

Waypoint type.

This option specifies how to represent point data in the draw file. @@ -543,29 +636,27 @@ and full path, of image files in a format that works with your DeLorme product. Note that this means that the .an1 file you generate will not work on any computer that does not have those images in the same place; this is part of the design of the an1 format and cannot be avoided. -

radius option

+

radius option

Radius for circles.

If the waypoint type is "circle", the "radius" option specifies the radius of the circles. By default, this is in miles, but it may be specified in kilometers by adding a 'k'. The default radius is 1/10 mile. -

DeLorme GPL (gpl)

+

DeLorme GPL (gpl)

This format can... -

  • +

    • read and write tracks -

    -

    This is the 'gpl' format as used in Delorme mapping +

This is the 'gpl' format as used in Delorme mapping products. It is a track format and contains little more than the tracklog of a GPS that was attached while driving. frontiernet.net -

DeLorme Street Atlas Plus (saplus)

+

DeLorme Street Atlas Plus (saplus)

This format can... -

  • +

    • read and write waypoints

    -

    This format is derived from the xcsv format, so it has all of the same options as that format. -

    This format is for Street Atlas USA 2004 Plus. +

    This format is for Delorme Street Atlas USA 2004 Plus and later.

    For geocachers importing data from a tool like GSAK or Spinner, import the file twice in XData. One will create a file with the Cache description as a hyperlink on the flag. This can clutter up @@ -576,33 +667,32 @@ assign field types, check the circle above Full Name and then next. The second time you import the file do not check any circle and in the second to last column, change URL to none and then click next. Use the same name you used the first time but add -Flag to it. -

DeLorme Street Atlas Route (saroute)

+

DeLorme Street Atlas Route (saroute)

This format can... -

  • +

    • read tracks -

    -

    +

This format reads route files from many Delorme mapping products. It supports the anr, rte, and rtd formats as either tracks or routes.

All options only apply to route files from newer (anr) versions of DeLorme software; older versions didn't store the turn information with the route. -

turns_important option

+

turns_important option

Keep turns if simplify filter is used.

This option only makes sense in conjunction with the 'simplify' filter. It ensures that the route simplification process will remove the points corresponding to turns only after it has removed all other route points. -

turns_only option

+

turns_only option

Only read turns; skip all other points.

This option causes GPSBabel to read only the waypoints associated with named turns. This should create a list of -waypoints that correspond to the itinerary from Street Atlas.

split option

+waypoints that correspond to the itinerary from Street Atlas.

split option

Split into multiple routes at turns.

This option causes GPSBabel to create separate routes for each street, creating a new route at each turn point. For obvious reasons, 'split' cannot be used at the same time as the -'turns_only' or 'turns_important' options.

controls option

+'turns_only' or 'turns_important' options.

controls option

Read control points as waypoint/route/none.

This option lets you read the control points (start, end, vias, and stops) for your route as well as the route @@ -612,47 +702,47 @@ control points as waypoints, or 'route', which creates an extra route named 'control points' containing just the control points in order. Note that if your goal is to create an arc or other CSV file, you should use 'none' (or not use this option, which is the same -thing.)

times option

+thing.)

times option

Synthesize track times.

This option causes GPSBabel to read the route as if it were a track, synthesizing times starting from the current time, using the estimated travel times specified in your route file (you can change your -travel speeds in the DeLorme product you used to create the route file.)

DeLorme XMap HH Native .WPT (xmap)

+travel speeds in the DeLorme product you used to create the route file.)

DeLorme XMap HH Native .WPT (xmap)

This format can... -

  • +

    • read and write waypoints

    -

    This format is derived from the xcsv format, so it has all of the same options as that format. -

    Delorme TopoUSA/XMap Conduit is one of the billion CSV -variants mentioned above. It's just like S&A with the addition of +

    Delorme TopoUSA/XMap Conduit is one of the bazillion +CSV variants +variants mentioned above. It's just like Delorme Streets & Atlas with the addition of a completely pointless line at the beginning and end of the file. This is the format used to hot-sync to XMap from withing TopoUSA. Done with -help of Dan Edwards.

DeLorme XMap/SAHH 2006 Native .TXT (xmap2006)

+help of Dan Edwards.

DeLorme XMap/SAHH 2006 Native .TXT (xmap2006)

This format can... -

  • +

    • read and write waypoints

    -

    This format is derived from the xcsv format, so it has all of the same options as that format. -

    Delorme XMap2006 Conduit is just like XMap, except there are +

    Delorme XMap2006 Conduit is just like +XMap +, except there are no spaces between fields and the coordinate format is slightly different. The completely pointless header and footer lines are the same, at least. Use this to create the XMapHHWptsSend.txt - file needed to sync to Street Atlas Handheld 2006.

    Note that in order to keep from creating duplicates on your handheld, you must first remove the file "XMapWptsDB" from your handheld, restart SAHH2006 on the handheld to create an empty database, and THEN sync the new file.

DeLorme XMat HH Street Atlas USA .WPT (PPC) (xmapwpt)

+ file needed to sync to Street Atlas Handheld 2006.

Note that in order to keep from creating duplicates on your handheld, you must first remove the file "XMapWptsDB" from your handheld, restart SAHH2006 on the handheld to create an empty database, and THEN sync the new file.

DeLorme XMat HH Street Atlas USA .WPT (PPC) (xmapwpt)

This format can... -

  • +

    • read and write waypoints

    -

    This format is derived from the xcsv format, so it has all of the same options as that format.

    Delorme XMapHandHeld Street Atlas USA is another of the -billion CSV variants. This is the format used by XmapHH SA USA on (at -least) PocketPC O/S. +billion CSV variants. +This is the format used by XmapHH SA USA on (at least) PocketPC O/S.

    This XMap is not the same as the simpler XMap format, which is used with Topo USA 4.0 @@ -676,13 +766,13 @@ of this chapter. It should also be noted that reading multiple files is indeed possible, but if you have more than a few points, it can be a task. For example: -

    gpsbabel -i xmapwpt -f Xmap1.wpt -f Xmap2.wpt -o mapsend -F mapsend.wpt

    +

    gpsbabel -i xmapwpt -f Xmap1.wpt -f Xmap2.wpt -o mapsend -F mapsend.wpt

    will read the two Xmap .wpt files and write one mapsend file. This is fine for a small handful of points, but could be quite cumbersome for folks like me who have 100+ waypoints loaded into XMap. For *nix folks, something as simple as: -

    cat *.wpt > /tmp/foo.wpt
    -gpsbabel -i xmapwpt -f foo.wpt -o mapsend -F mapsend.wpt 

    +

    cat *.wpt > /tmp/foo.wpt +gpsbabel -i xmapwpt -f foo.wpt -o mapsend -F mapsend.wpt

    will do the trick just fine.

     #!/full/path/to/perl
    @@ -691,9 +781,11 @@ $TARGETDIR = @ARGV[1];
     $FILENAME  = @ARGV[2];
     
     if (! $FILENAME) {
    -    print "Usage: xmap_split.pl INPUT_FILE OUTPUT_DIRECTORY FILENAME_BASE\n";
    +    print "Usage: xmap_split.pl " . 
    +	"INPUT_FILE OUTPUT_DIRECTORY FILENAME_BASE\n";
         print " (i.e. xmapl_split.pl points.wpt /tmp/points GPSB)\n";
    -    print " (created GPSB0001-GPSBXXXX in /tmp/points/ from points.wpt)\n";
    +    print " (created GPSB0001-GPSBXXXX " .
    +	" in /tmp/points/ from points.wpt)\n";
         exit;
     }
     
    @@ -703,7 +795,8 @@ while (<INFILE>) {
         $lc++;
         $filename = sprintf("%s/Gpsb%04d.wpt", $TARGETDIR, $lc);
     
    -    open (OUTFILE, ">$filename") || die "Cannot open $filename for write!\n";
    +    open (OUTFILE, ">$filename") || 
    +	die "Cannot open $filename for write!\n";
     
         print OUTFILE $_;
     
    @@ -712,27 +805,23 @@ while (<INFILE>) {
     
     exit;
     
    -

    Contributed to GPSBabel by Alex Mottram.

EasyGPS binary format (easygps)

+

Contributed to GPSBabel by Alex Mottram.

EasyGPS binary format (easygps)

This format can... -

  • +

    • read and write waypoints -

    -

    This is the binary file format used by EasyGPS. This +

This is the binary file format used by EasyGPS format is seemingly being phased out in favor of GPX in newer versions of EasyGPS, but this allows conversions to and from the old binary .loc format. -

- http://www.easygps.com/ -

Information about and sketchy code to implement this file +

Information about and sketchy code to implement this file format were provided by Eric Cloninger. -

FAI/IGC Flight Recorder Data Format (igc)

+

FAI/IGC Flight Recorder Data Format (igc)

This format can... -

  • +

    • read and write tracks -

    • +

    • read and write routes

    -

    FAI/IGC Data File -- Used by the international gliding community to record gliding flights. IGC files can be converted to and from tracks representing recorded flights, and routes representing @@ -761,36 +850,36 @@ will not be accepted as proof of a flight.

    A track stored in another format (GPX for example) representing a recorded flight can be converted into an IGC file: -

    gpsbabel -i gpx -f mytrk.gpx -o igc -F myflight.igc

    +

    gpsbabel -i gpx -f mytrk.gpx -o igc -F myflight.igc

    If multiple track segments are provided in the input file, the one with the most points will be used.

    A route stored in another format representing a task declaration can be converted into an IGC file: -

    gpsbabel -i gpx -f myrte.gpx -o igc -F mytask.igc

    +

    gpsbabel -i gpx -f myrte.gpx -o igc -F mytask.igc

    A route and a track in other formats can be included into a single IGC file: -

    gpsbabel -i gpx -f mytrk.gpx -f myrte.gpx -o igc -F myflight.igc

    +

    gpsbabel -i gpx -f mytrk.gpx -f myrte.gpx -o igc -F myflight.igc

    A similar result can be obtained by downloading the track log and routes directly from a GPS device connected to a PC. For example to create an IGC file from data recorded in a Garmin GPS connected to the first serial port of a PC running Linux: -

    gpsbabel -t -r -i garmin -f /dev/ttyS0 -o igc -F myflight.igc

    +

    gpsbabel -t -r -i garmin -f /dev/ttyS0 -o igc -F myflight.igc

    For Windows operating systems: -

    gpsbabel -t -r -i garmin -f com1 -o igc -F myflight.igc

    +

    gpsbabel -t -r -i garmin -f com1 -o igc -F myflight.igc

    A waypoint file in another format containing a waypoint whose short name is "PILOT" can be merged into an IGC file. The description field of the waypoint will be used for the pilot name in the IGC file header: -

    gpsbabel -i gpx -f mytrk.gpx -f myrte.gpx -f mywpt.gpx -o igc -F myflight.igc
    -gpsbabel -w -t -r -i garmin -f /dev/ttyS0 -o igc -F myflight.igc

    +

    gpsbabel -i gpx -f mytrk.gpx -f myrte.gpx -f mywpt.gpx -o igc -F myflight.igc +gpsbabel -w -t -r -i garmin -f /dev/ttyS0 -o igc -F myflight.igc

    Some formats such as GPX allow routes, tracks and waypoints to exist in the same file and can be used to fully populate an IGC file: -

    gpsbabel -i gpx -f myall.gpx -o igc -F myflight.igc

Converting from IGC format

+

gpsbabel -i gpx -f myall.gpx -o igc -F myflight.igc

Converting from IGC format

Data in an IGC file can be converted into other formats. For example to generate OziExplorer files containing tracks representing the recorded flight (myozi.plt) and routes representing declared tasks (myozi.rte): -

gpsbabel -i igc -f myflight.igc -o ozi -F myozi

+

gpsbabel -i igc -f myflight.igc -o ozi -F myozi

Or to GPX format: -

gpsbabel -i igc -f myflight.igc -o gpx -F myflight.gpx

+

gpsbabel -i igc -f myflight.igc -o gpx -F myflight.gpx

Header information from the IGC file will be written to the description field of the track(s).

@@ -800,19 +889,19 @@ tracks. The latitude, longitude and timestamps in the tracks will be identical.

Merging into IGC format

A route stored in another format can be merged with an existing IGC file that has no task declaration, to generate a new IGC file with a task declaration: -

gpsbabel -i igc -f myflight.igc -i gpx -f myrte.gpx -o igc -F mynew.igc

+

gpsbabel -i igc -f myflight.igc -i gpx -f myrte.gpx -o igc -F mynew.igc

A two dimensional (lat/lon) track recorded during a flight by a GPS receiver can be merged with a one dimensional (altitude) track recorded during the same flight by a barograph instrument. The result is a three dimensional IGC file representing the flight: -

gpsbabel -i gpx -f baro.gpx -i igc -f my2D.igc -o igc -F my3D.igc

+

gpsbabel -i gpx -f baro.gpx -i igc -f my2D.igc -o igc -F my3D.igc

The same can be acheived by downloading directly from a barograph instrument supported by GPSBabel. For example with a Brauniger IQ Comp GPS variometer: -

gpsbabel -i baroiq -f /dev/ttyS0 -i igc -f my2D.igc -o igc,timeadj=auto -F my3D.igc

+

gpsbabel -i baroiq -f /dev/ttyS0 -i igc -f my2D.igc -o igc,timeadj=auto -F my3D.igc

or: -

gpsbabel -i baroiq -f com1 -i igc -f my2D.igc -o igc,timeadj=auto -F my3D.igc

+

gpsbabel -i baroiq -f com1 -i igc -f my2D.igc -o igc,timeadj=auto -F my3D.igc

(Documentation contributed by Chris Jones, Aug 2004) -

timeadj option

+

timeadj option

(integer sec or 'auto') Barograph to GPS time diff.

Sometimes there is a discrepancy between the internal clock in the barograph @@ -820,31 +909,30 @@ instrument and GPS time which can result in the altitude and ground positions not correlating correctly. This can be corrected manually by passing the time difference in seconds between the two time domains through the "timeadj" parameter. This can be any positive or negative integer: -

gpsbabel -i gpx -f baro.gpx -i igc -f my2D.igc -o igc,timeadj=27 -F my3D.igc

+

gpsbabel -i gpx -f baro.gpx -i igc -f my2D.igc -o igc,timeadj=27 -F my3D.igc

GPSBabel can also attempt to deduce the time difference automatically. This is done by comparing the time that it thinks that you landed on the GPS track and the barograph and adjusting accordingly: -

gpsbabel -i gpx -f baro.gpx -i igc -f my2D.igc -o igc,timeadj=auto -F my3D.igc

Franson GPSGate Simulation (gpssim)

+

gpsbabel -i gpx -f baro.gpx -i igc -f my2D.igc -o igc,timeadj=auto -F my3D.igc

Franson GPSGate Simulation (gpssim)

This format can... -

  • +

    • write waypoints -

    • +

    • write tracks -

    • +

    • write routes

    -

    This is a write-only format used to feed waypoints, tracks, and routes into Franson Technolgies' GpsGate simulator.

    To use these files in GpsGate, select 'Simulator' and then "File->Open". -

    wayptspd option

    +

    wayptspd option

    Default speed for waypoints (knots/hr).

    This option specifies the speed of the simulation in knots. -

    split option

    +

    split option

    Split input into separate files.

    When this option is specified, GPSBabel will split split the output into multiple files using the output filename @@ -852,16 +940,15 @@ and the barograph and adjusting accordingly:

    mytrip-waypoints.gpssim - will contain the waypoints.
    mytrip-track0000.gpssim - will contain the first track.
    mytrip-track0001.gpssim - will contain the second track.
    ... and so on.
    mytrip-route0000.gpssim - will contain the first route.
    mytrip-route0001.gpssim - will contain the seconds route.
    ... and so on.

    Valid values for this option are 0 (off) and 1 (on). The default is '0'. -

    Fugawi (fugawi)

    +

Fugawi (fugawi)

This format can... -

  • +

    • read and write waypoints

    -

    This format is derived from the xcsv format, so it has all of the same options as that format. -

    This was a requested CSV format, *not* the proprietary -binary format used by Fugawi. Like any other CSV format, GPSBabel +

    This was a requested CSV format, and is not the proprietary +binary format used by Fugawi. Like any other CSV format, GPSBabel cannot read tracks in this format, but converting a track into it and then importing as track in Fugawi works.

    It is known to work with Fugawi V3.1.4.635. When importing/exporting waypoints, one has to specify the order of fields @@ -869,68 +956,74 @@ as follows (names of fields may depend on the language used by Fugawi):

    - Name
    - Comment
    - Description
    - Latidude
    - Longitude
    - Altitude (metres)
    - Date (yyyymmdd/yymmdd)
    - Time of day (hhmmss)

    When importing tracks, use "[ignore]" instead of "Name", "Comment" and "Description".

    http://www.fugawi.com/ -

Garmin 301 Custom position and heartrate (garmin301)

+

Garmin 301 Custom position and heartrate (garmin301)

This format can... -

  • +

    • read and write waypoints

    -

    This format is derived from the xcsv format, so it has all of the same options as that format.

    This is a very simple format that -is most useful for exporting data from a Garmin301 to other programs +is most useful for exporting data from units that support heart rate +data such as +Garmin Forerunner 301™, +Garmin Forerunner 305™, and +Garmin Edge 305™, and +to other programs for analysis. It's a simple comma delimited format that includes the timestamp, 3D position information and heart rate so you can pull it -into a spreadsheet or graphing program.

Garmin Logbook XML (glogbook)

+into a spreadsheet or graphing program.

Garmin Logbook XML (glogbook)

This format can... -

  • +

    • read and write tracks -

    -

    This is the XML format used by the Garmin Logbook product -that ships with Forerunner and Foretrex. http://www.garmin.com -

Garmin MapSource - gdb (gdb)

+

This is the XML format used by the Garmin Logbook product +that ships with Forerunner and Foretrex. +As of early 2006, this program is apparently been discontinued in favor of +Garmin Training Center. + +See: http://www.garmin.com +

Garmin MapSource - gdb (gdb)

This format can... -

  • +

    • read and write waypoints -

    • +

    • read and write tracks -

    • +

    • read and write routes -

    -

    +

Support for the "Garmin GPS Database" format used by -default in MapSource versions since release 6.0. By default GPSBabel creates +default in MapSource™ versions since release 6.0 of +that product. By default GPSBabel creates gdb files of version 2. Version 2 is used in Mapsource 6.3 and 6.5.

Garmin GPS database is an undocumented file format. The basic info for this module came from the existing MapSource conversion code. -

cat option

+

cat option

Default category on output (1..16).

This option specifies the default category for gdb output. It should be a number from 1 to 16. -

ver option

+

ver option

Version of gdb file to generate (1,2).

This option specifies the data format version for the output file. Version 2 is the default. Currently, the only other valid value for this option is 1. -

via option

+

via option

Drop route points that do not have an equivalent waypoint (hidden points).

This option instructs GPSBabel to drop hidden (calculated) points from routes. -

Garmin MapSource - mps (mapsource)

+

Garmin MapSource - mps (mapsource)

This format can... -

  • +

    • read and write waypoints -

    • +

    • read and write tracks -

    • +

    • read and write routes -

    -

    +

This format supports the Garmin Mapsource™ product family.

@@ -952,143 +1045,148 @@ all handled, but map sets are ignored.

Information on the Garmin Mapsource format was provided by Ian Cowley and Mark Bradley. The code was implemented by Robert Lipe and Mark Bradley. -

snlen option

+

snlen option

Length of generated shortnames.

This option specifies the length of generated short names on output. The default is 10 characters. -

snwhite option

+

snwhite option

Allow whitespace synth. shortnames.

This option specifies whether to allow whitespace (space, tab, etc.) in generated short names on output. The default is to not allow whitespace. -

mpsverout option

+

mpsverout option

Version of mapsource file to generate (3,4,5).

This option specifies the format version for the output file. The default is version 5, as noted above. Supported versions are 3, 4, and 5. -

mpsmergeout option

+

mpsmergeout option

Merge output with existing file.

This option causes the output to be merged with a pre-existing output file. This allows MapSource sections that aren't handled by GPSBabel (e.g. map sets) to be preserved. -

mpsusedepth option

+

mpsusedepth option

Use depth values on output (default is ignore).

This option causes GPSBabel to write depth values for waypoints. Most input formats do not support depth values, so the default is to not write them. -

mpsuseprox option

+

mpsuseprox option

Use proximity values on output (default is ignore).

This option causes GPSBabel to write proximity values for waypoints. Most input formats do not support proximity values, so the default is to not write them. -

Garmin MapSource - txt (tab delimited) (garmin_txt)

+

Garmin MapSource - txt (tab delimited) (garmin_txt)

This format can... -

  • +

    • read and write waypoints -

    • +

    • read and write tracks -

    • +

    • read and write routes

    -

    This is a textual format that contains nearly all of the information -contained in the MapSource main format, GDB. +contained in the MapSource™ main format, GDB. This format also contains some computed values such as distances between routepoints and trackpoints, speed, and course (heading).

    The main goal of garmin_txt is to make aviation data more available. Because -MapSource supports only the export, GPSBabel gives you the possibility to -bring aviation data into MapSource. +MapSource™ supports only the export, GPSBabel gives you the possibility to +bring aviation data into MapSource™.

    -During the export with MapSource, some fields are written using local settings -of MapSource and Windows. These include grid format, gps datum, distance and +During the export with MapSource™, some fields are written using local settings +of MapSource™ and Windows. These include grid format, gps datum, distance and temperature units, and the representation of date and time fields. GPSBabel tries to read all items automatically. Problems with date and time format can be solved with the 'date' and 'time' options. -

    Example 3.1. Command showing garmin_txt output with all options

    gpsbabel -i garmin_txt,date="MM/DD/YYYY",time="hh:mm:ss xx" -f in.txt -o garmin_txt,date="DD.MM.YYYY",datum="WGS 72",dist=m,prec=6,temp=c,time="HH:mm:ss",utc=+2 -F out.txt

    date option

    +

    Example 3.1. Command showing garmin_txt output with all options

    gpsbabel -i garmin_txt,date="MM/DD/YYYY",time="hh:mm:ss xx" -f in.txt -o garmin_txt,date="DD.MM.YYYY",datum="WGS 72",dist=m,prec=6,temp=c,time="HH:mm:ss",utc=+2 -F out.txt


    date option

    Read/Write date format (i.e. yyyy/mm/dd).

    This option specifies the input and output format for the date. The format is written similarly to those in Windows. An example format is "YYYY/MM/DD". -

    datum option

    +

    datum option

    GPS datum (def. WGS 84).

    This option specifies the datum to be used on output. Valid values for this option are listed in Appendix A, Supported Datums. -

    dist option

    +

    dist option

    Distance unit [m=metric, s=statute].

    This option specifies the unit to be used when outputting distance values. Valid values are M for metric (m/km/kph) or S for statute (ft/mi/mph). -

    prec option

    +

    grid option

    + Write position using this grid.. +

    + This value specifies the grid to be used on write. +

    Table 3.1. Grid values for garmin_txt

    # idxshortfile-headersample
    0dddLat/Lon hddd.ddddd S26.25333 E27.92333
    1dmLat/Lon hddd°mm.mmN33 56.539 W118 24.471
    2dmLat/Lon hddd°mm'ss.sS25 25 26.8 E28 06 07.3
    3bngBritish National GridTQ 18919 69392

    + Idx or short are valid params for this option. +

    prec option

    Precision of coordinates.

    This option specifies the precision to be used when writing coordinate values. Precision is the number of digits after the decimal point. The default precision is 3. -

    temp option

    +

    temp option

    Temperature unit [c=Celsius, f=Fahrenheit].

    This option specifies the unit to be used when writing temperature values. Valid values are C for Celsius or F for Fahrenheit. -

    time option

    +

    time option

    Read/Write time format (i.e. HH:mm:ss xx).

    This option specifies the input and output format for the time. The format is written similarly to those in Windows. An example format is "hh:mm:ss xx". -

    utc option

    +

    utc option

    Write timestamps with offset x to UTC time.

    This option specifies the local time zone to use when writing times. It is specified as an offset from Universal Coordinated Time (UTC) in hours. Valid values are from -23 to +23. -

    Garmin PCX5 (pcx)

    +

Garmin PCX5 (pcx)

This format can... -

  • +

    • read and write waypoints -

    • +

    • read and write tracks -

    • +

    • read and write routes -

    -

    Garmin documents only PCX5, an older format limited to +

Garmin documents only PCX5, an older format limited to the lame NMEA six-character waypoint names that's treated as a second-class citizien in current versions of MapSource. In Mapsource, use file->import to read these files. If you name the files *.wpt, -Mapsource will find them easier. +Mapsource will find them more easily.

In general, you should prefer the "mapsource" file format to this one. -

deficon option

+

This format has been extended to handle many - but not all - + files from GPS Utility. If you encounter something that GPSBabel does not handle well, use +the free version of GPSUtil to read it and save as something more common. +

deficon option

Default icon name. -

cartoexploreur option

+

cartoexploreur option

Write tracks compatible with Carto Exploreur. -

Garmin POI database (garmin_poi)

+

Garmin POI database (garmin_poi)

This format can... -

  • +

    • read and write waypoints

    -

    This format is derived from the xcsv format, so it has all of the same options as that format.

    The Garmin POI loader loads custom points of interest into certain models of Garmin GPS receivers. (As of this writing, only the models introduced in 2005 and later are supported. See Garmin's site for more info.) -This is the format readable that that program.

Garmin serial/USB protocol (garmin)

+This is the format readable that that program.

Garmin serial/USB protocol (garmin)

This format can... -

  • +

    • read and write waypoints -

    • +

    • read and write tracks -

    • +

    • read and write routes -

    -

    +

GPSBabel supports a wide variety of Garmin hardware via serial on most operating systems and USB on Windows, Linux, and OS X.

@@ -1096,10 +1194,12 @@ This is the format readable that that program.

- Supported models on USB include -

Edge 205Foretrex 201GPSMAP 60CSNuvi 350[1]StreetPilot 7500
Edge 305Foretrex 301GPSMAP 60CSXNuvi 360[1]StreetPilot c310
eTrex Legend CGPSMAP 195GPSMAP 60CXQuestStreetPilot c320
eTrex LegendCXGPSMAP 276CGPSMAP 76CQuest IIStreetPilot c330
eTrex Venture CGPSMAP 295GPSMAP 76CSStreetPilot 2610StreetPilot c340
eTrex Venture CXGPSMAP 296CGPSMAP 76CSXStreetPilot 2620StreetPilot c510[1]
eTrex VistaCGPSMAP 378GPSMAP 76CXStreetPilot 2650StreetPilot c530[1]
eTrex Vista CXGPSMAP 396GPSMAP 96StreetPilot 2720StreetPilot c550[1]
Forerunner 205GPSMAP 478GPSMAP 96CStreetPilot 2730StreetPilot i2
Forerunner 301GPSMAP 496Nuvi 300[1]StreetPilot 2820StreetPilot i3
Forerunner 305GPSMAP 60CNuvi 310[1]StreetPilot 7200StreetPilot i5

-

and most serial units including: -

eMapeTrex VistaGeko 301GPS III StreetPilot III
eTrex CamoeTrex YellowGPS 12CX GPS III+ StreetPilot III+
eTrex LegendForerunner 201GPS 12Map GPS II  
eTrex SummitForetrex 201GPS 12 GPS II+  
eTrex VentureGeko 201GPS 12XL GPS V 

+ Supported Garmin GPS receivers with USB include +

AstroGPSMAP 276CGPSMAP 96CStreetPilot 7200
Edge 205GPSMAP 295Nuvi 300[2]StreetPilot 7500
Edge 305GPSMAP 296CNuvi 310[2]StreetPilot c310
eTrex Legend CGPSMAP 378Nuvi 350[2]StreetPilot c320
eTrex LegendCXGPSMAP 396Nuvi 370[2]StreetPilot c330
eTrex Venture CGPSMAP 478Nuvi 660[2]StreetPilot c340
eTrex Venture CXGPSMAP 496Nuvi 670[2]StreetPilot c510[2]
eTrex VistaCGPSMAP 60CNuvi 680[2]StreetPilot c530[2]
eTrex Vista CXGPSMAP 60CSQuestStreetPilot c550[2]
Forerunner 205GPSMAP 60CSXQuest IIStreetPilot c580[2]
Forerunner 301GPSMAP 60CXStreetPilot 2610StreetPilot i2
Forerunner 305GPSMAP 76CStreetPilot 2620StreetPilot i3
Foretrex 201GPSMAP 76CSStreetPilot 2650StreetPilot i5
Foretrex 301GPSMAP 76CSXStreetPilot 2720Zumo 450[2]
GPS 18[1]GPSMAP 76CXStreetPilot 2730Zumo 550[2]
GPSMAP 195GPSMAP 96StreetPilot 2820 

+

the following Bluetooth Garmin products: +

GPS 10[1]   

+

and most serial Garmin GPS receivers including: +

eMapeTrex YellowGPS 12Map GPS II+
eTrex CamoForerunner 201GPS 12 GPS V
eTrex LegendForetrex 201GPS 12XL StreetPilot III
eTrex SummitGeko 201GPS III StreetPilot III+
eTrex VentureGeko 301GPS III+  
eTrex VistaGPS 12CX GPS II  

None of the GPSBabel developers has access to every model on that list, but we've received reports of success and/or have reasonable @@ -1113,26 +1213,23 @@ This is the format readable that that program.

- To communicate with a unit serially, use the name of that - serial port such as "COM1" or "/dev/cu.serial". + To communicate with a Garmin GPS serially, use the name of that + serial port such as COM1 or /dev/cu.serial.

- To communicate via USB use "usb:" as the filename on all OSes. - Thus, to read the waypoints from a Garmin USB unit and write + To communicate via USB use usb: as the filename on all OSes. + Thus, to read the waypoints from a Garmin USB receiver and write them to a GPX file: - -

gpsbabel -i garmin -f usb: -o gpx -F blah.gpx

- -

+

gpsbabel -i garmin -f usb: -o gpx -F blah.gpx

If you have multiple units attached via USB, you may provide a unit number, with zero being the implied default. So if you have three USB models on your system, they can be addressed as - "usb:0", "usb:1", and "usb:2". To get a list of recognized devices, + usb:0, usb:1, and usb:2. To get a list of recognized devices, specifiy a negative number such as: -

gpsbabel -i garmin -f usb:-1

+

gpsbabel -i garmin -f usb:-1

When reporting problems with the Garmin format, be sure to include the full unit model, firmware version, and be prepared to offer -debugging dumps by adding "-D9" to the command line, like: -

 gpsbabel -D9 -i garmin -f usb: -o gpx -F blah.gpx

+debugging dumps by adding -D9 to the command line, like: +

gpsbabel -D9 -i garmin -f usb: -o gpx -F blah.gpx

Custom icons are supported on units that support that. Neither GPSBabel nor your firmware know what is associated with any given slot number. They don't know that the picture you placed in the @@ -1145,12 +1242,16 @@ so they are named 'Custom 0' through 'Custom 511'. mode" in setup and that nothing else (PDA hotsync programs, gpsd, getty, pppd, etc.) is using the serial port.

- For models connected via USB, we recommend use of the 'usb:' + For models connected via USB, we recommend use of the usb: filename. For this to work on Windows, you must install the Garmin driver. For Linux, this will fail if have the garmin_gps kernel module loaded. See the Operating System Notes for details. -

snlen option

+

+This module also supports realtime tracking +which allows realtime position reports from a Garmin GPS receiver over USB +or serial. +

snlen option

Length of generated shortnames.

This option overrides the internal logic to figure out how many characters an addressed Garmin GPS will support when using the '-s' smartname @@ -1158,10 +1259,10 @@ option. This should be necessary only if you have a receiver type that GPSBabel doesn't know about or if you want to "dumb down" one unit to match another, such as wanting waypoint names in a StreetPilot 2720 (which supports 20 character names) to exactly match those in a 60CS (which supports 10). -

snwhite option

+

snwhite option

Allow whitespace synth. shortnames.

This options controls whether spaces are allowed in generated -smart names when using the '-s' option.

deficon option

+smart names when using the '-s' option.

deficon option

Default icon name.

This option specifies the icon or waypoint type to write for each waypoint on @@ -1175,13 +1276,12 @@ Value specified may be a number from the Garmin Protocol Spec or a name as described in the Appendix B, Garmin Icons.

This option has no effect on input. -

get_posn option

+

get_posn option

Return current position as a waypoint.

This options gets the current longtitude and latitude from the attached GPS device and returns it as a single waypoint for further processing. For example, to return the current position from a USB Garmin to a KML file: -

gpsbabel -i garmin,get_posn -f usb: -o kml -F myposition.kml

-

power_off option

+

gpsbabel -i garmin,get_posn -f usb: -o kml -F myposition.kml

power_off option

Command unit to power itself down.

This command forces an immediate powerdown of the addressed Garmin receiver. It is ignored on hardware that does not support this command. @@ -1189,19 +1289,16 @@ Obviously, further processing once you have sent a "power off" command to a unit that supports it is rather futile, so place this option carefully in your command. -

gpsbabel -o garmin,power_off -F /dev/ttyS0

-

category option

+

gpsbabel -o garmin,power_off -F /dev/ttyS0

category option

Category number to use for written waypoints.

This numeric option will force waypoints to be written with that category number when sending to a Garmin receiver that has category -support. It is ignored on receivers without that capability.

Garmin Training Centerxml (gtrnctr)

+support. It is ignored on receivers without that capability.

Garmin Training Centerxml (gtrnctr)

This format can... -

  • +

    • write tracks

    -

    -Garmin Training Center is the successor to Garmin' Logbook program -for their workout units. It is a free upgrade. +GPSBabel has limited support for Garmin Training Center files. That program is the successor to Garmin' Logbook program for their workout units. It is a free upgrade.

    This format is somewhat underachieving in GPSBabel. It is a write-only format; we never read it. The bigger problem, however, is a fundamental @@ -1212,13 +1309,12 @@ of Training Center are different - it deals in concepts like laps and calories which are rather alien to GPSBabel and most of the formats we support. As such, while we can describe the tracks pretty accurately, things like calories and heart zone tracking are not supported. -

Geocaching.com .loc (geo)

+

Geocaching.com .loc (geo)

This format can... -

  • +

    • read and write waypoints

    -

    -This format supports the Geocaching.com/EasyGPS ".loc" format. This format +This format supports the Geocaching.com/EasyGPS ".loc" format. This format was created specifically for Geocaching.com and is not the same as the standard EasyGPS .loc format. See the EasyGPS or GPX formats for more general EasyGPS support. @@ -1226,7 +1322,7 @@ or GPX formats for more general Eas This is a simple XML-based format containing only very basic information about geocaches. If you can use the GPX format instead, you should consider doing so as it is a much richer format. -

    deficon option

    +

    deficon option

    Default icon name.

    This option specifies the icon or waypoint type to write for each waypoint on @@ -1239,7 +1335,7 @@ overrides any icon description that might be in the input file. There is no list of valid values for this option.

    This option has no effect on input. -

    nuke_placer option

    +

    nuke_placer option

    Omit Placer name.

    If this option is specified, GPSBabel will not read geocache placer information @@ -1247,89 +1343,86 @@ from a .loc file on input. That is, it will ignore any placeer names in the input file.

    This option has no effect on output. -

    GeocachingDB for Palm/OS (gcdb)

    +

GeocachingDB for Palm/OS (gcdb)

This format can... -

  • +

    • read and write waypoints -

    -

    This is the GeocachingDB by DougsBrat. It works with v2 -and v3 of this program. See vip.hyperusa.com -

GEOnet Names Server (GNS) (geonet)

+

This is format for the + +GeocachingDB program by DougsBrat. It works with v2 +and v3 of this program. +

GEOnet Names Server (GNS) (geonet)

This format can... -

  • +

    • read and write waypoints

    -

    This format is derived from the xcsv format, so it has all of the same options as that format.

    Input support for the GEOnet Names Server (GNS) country file structure. Export to this format is not possible, as this format has too many fields that we never get populated by any other -format.

GeoNiche .pdb (geoniche)

+format.

GeoNiche .pdb (geoniche)

This format can... -

  • +

    • read and write waypoints -

    -

    Geoniche is a Palm/OS application oriented for the -off-road user. This module was contributed by Rick Richardson. See -nwlink.com -

    dbname option

    +

Geoniche is a Palm/OS application oriented for the +off-road user. This module was contributed by Rick Richardson. +

dbname option

Database name (filename).

This option specifies the database name for the output file. This name is not the same thing as the file name on your computer; this is the name that appears in the file browser on your handheld. -

category option

+

category option

Category name (Cache).

This option specifies the name of the category in which to place the waypoints. If this option is not specified, the default category is "Cache". -

Google Earth (Keyhole) Markup Language (kml)

+

Google Earth (Keyhole) Markup Language (kml)

This format can... -

  • +

    • read and write waypoints -

    • +

    • read and write tracks -

    • +

    • read and write routes -

    -

    +

KML, the Keyhole Markup Language, is used by Keyhole and -Google Earth. There are features in this file format that GPSBabel +Google Earth. There are features in this file format that GPSBabel doesn't support - such as camera views - but waypoints, tracks, and routes work well.

Google Earth also uses GPSBabel internally for receiver communications and several file format imports and exports. -

deficon option

+

deficon option

Default icon name.

This option specifies the default name for waypoint icons -

lines option

+

lines option

Export linestrings for tracks and routes.

When this option is nonzero, GPSBabel draws lines between points in tracks and routes. The default value for this option is 1, which causes lines to be drawn by default. To disable line-drawing, specify lines=0. -

points option

+

points option

Export placemarks for tracks and routes.

When this option is nonzero, GPSBabel draws placemarks for tracks and routes. The default value for this option is 1, which causes placemarks to be drawn. To disable drawing of placemarks, specify points=0. -

line_width option

+

line_width option

Width of lines, in pixels.

This option specifies the width of the drawn lines in pixels. The default value is six pixels. -

line_color option

+

line_color option

Line color, specified in hex AABBGGRR.

This option specifies the line color as a hexadecimal number in AABBGGRR format, where A is alpha, B is blue, G is green, and R is red. -

floating option

+

floating option

Altitudes are absolute and not clamped to ground.

When this option is nonzero, altitudes are allowed to float above or below @@ -1338,7 +1431,7 @@ clamped to the ground. Specify floating=1 to allow float.

This option is more useful to pilots than to hikers. -

extrude option

+

extrude option

Draw extrusion line from trackpoint to ground.

This option is a boolean flag to specicy whether Google Earth should @@ -1346,7 +1439,7 @@ draw lines from trackpoints to the ground. It defaults to '0', which means no extrusion lines are drawn. The option of '1' is, of course, most useful for points that aren't actually on the ground such as those be captured from planes. -

trackdata option

+

trackdata option

Include extended data for trackpoints (default = 1).

This is a boolean flag that controls @@ -1355,29 +1448,28 @@ By default computed speed, timestamps, and so on are written with the default of '1' for this option. If you are writing large tracks and do not value this information, you can reduce the size of the generated file substantially by turning this flag off by setting it to '0'. -

units option

+

units option

Units used when writing comments ('s'tatute or 'm'etric).

Units is a simple option. Specify 's' for "statute" (miles, feet, and other things that don't sensibly convert to each other, but are craved by Americans) or 'm' for "metric". -

labels option

+

labels option

Display labels on track and routepoints (default = 1).

When this option is zero, no labels are added for track and route points. This option defaults to one, so labels are added by default. -

max_position_points option

+

max_position_points option

Retain at most this number of position points (0 = unlimited).

This option allows you to specify the number of points kept in the 'snail trail' generated in the realtime tracking mode. -

Google Maps XML (google)

+

Google Maps XML (google)

This format can... -

  • +

    • read tracks -

    -

    This format is designed to read the XML emitted when you -tack "&output=js" onto the end of a Google Maps route URL (use +

This format is designed to read the XML emitted when you +tack "&output=js" onto the end of a Google Mapsroute URL (use the "link to this page" option to get a usable URL.) This allows you to plan a route using Google Maps, then download it and use it in your own mapping program or GPS receiver. To get a file suitable for use @@ -1404,39 +1496,35 @@ TO="1060 W. Addison St, Chicago, IL" wget -O - "http://maps.google.com/maps?q=$FROM to $TO&output=js" \ 2&>/dev/null >google_map.js gpsbabel -i google -f google_map.js -o gpx -F google_map.gpx -

GpilotS (gpilots)

+

GpilotS (gpilots)

This format can... -

  • +

    • read and write waypoints -

    -

    This is a Palm/OS file format for GPilotS. It was tested -against version 6.2. -

    - http://www.cru.fr/perso/cc/GPilotS/ -

    Neither tracks nor routes are supported at this -time.

    dbname option

    +

This is a Palm/OS file format for + GPilotS. + It was tested against version 6.2 of GPilotsS +

Neither tracks nor routes are supported at this +time.

dbname option

Database name.

This option specifies the database name for the output file. This name is not the same thing as the file name on your computer; this is the name that appears in the file browser on your handheld. -

GPS TrackMaker (gtm)

+

GPS TrackMaker (gtm)

This format can... -

  • +

    • read and write waypoints -

    • +

    • read and write tracks -

    • +

    • read and write routes -

    -

    Input and output support for waypoints, tracks and routes in +

Input and output support for waypoints, tracks and routes in the GPS TrackMaker - binary format.

Code implemented by Gustavo Niemeyer.

GPSBabel arc filter file (arc)

+ binary format.

Code implemented by Gustavo Niemeyer.

GPSBabel arc filter file (arc)

This format can... -

  • +

    • read and write waypoints

    -

    This format is derived from the xcsv format, so it has all of the same options as that format.

    @@ -1444,32 +1532,36 @@ This format is used by GPSBabel itself as the input to the arc and polygon filters. See those filters for more information. -

GpsDrive Format (gpsdrive)

+

+The arc format reads two numeric fields, a latitude and a longitude, +in any format recognized as human +readable and writes as simple degrees decimal. It really is +intended for GPSBabel's own internal use more than general use, though +it turns out to be a convenient way of expressing simple polylines and +polygons. +

GpsDrive Format (gpsdrive)

This format can... -

  • +

    • read and write waypoints

    -

    This format is derived from the xcsv format, so it has all of the same options as that format.

    GpsDrive way.txt file format. A space seperated format file. Tested against GpsDrive v 1.30 found at kraftvoll.at. -Contributed by Alan Curry.

GpsDrive Format for Tracks (gpsdrivetrack)

+Contributed by Alan Curry.

GpsDrive Format for Tracks (gpsdrivetrack)

This format can... -

  • +

    • read and write waypoints

    -

    This format is derived from the xcsv format, so it has all of the same options as that format.

    Format used by GpsDrive to save tracks. Like GPSDRIVE a space seperated format file. See above for a link to GpsDrive. -Contributed by Tobias Minich.

GPSman (gpsman)

+Contributed by Tobias Minich.

GPSman (gpsman)

This format can... -

  • +

    • read and write waypoints

    -

    This format is derived from the xcsv format, so it has all of the same options as that format.

    GPS Manager @@ -1478,52 +1570,56 @@ can read and write formats GPSBabel doesn't understand. The format defaults are not supported.

    This format is documented at the GPS Manager doc site. -

GPSPilot Tracker for Palm/OS (gpspilot)

+

GPSPilot Tracker for Palm/OS (gpspilot)

This format can... -

  • +

    • read and write waypoints -

    -

    The file format for GPSPILOT gpspilot.com was provided by Ron +

The file format for GPSPILOT gpspilot.com was provided by Ron Parker. The output from this module has been tested with GPSPilot Tracker v5.05sx, but it is based on reverse-engineering so it may not work with all versions of all GPSPilot products. It had read-only support for Airport, Navaid, City and Landmark files but will read and -write Point files.

dbname option

+write Point files.

dbname option

Database name.

This option specifies the database name for the output file. This name is not the same thing as the file name on your computer; this is the name that appears in the file browser on your handheld. -

gpsutil (gpsutil)

+

gpsutil (gpsutil)

This format can... -

  • +

    • read and write waypoints -

    -

    GPSUtil has a simple file format of this program that runs +

The format we call gpsutil is a simple file format used by a program that runs on POSIX- compliant OSes like UNIX and Linux. Reads and writes of -this format are reliable. (I've also contributed to this program.) -It's available at cs.uakron.edu.

GPX XML (gpx)

+this format are very reliable. (The lead +developer of GPSBabel also contributed to this that 'gpsutil' +the early days.)

+ Note that 'gpsutil' is a different format - and program - than the one called GPS Utility; for that one, you should probably use our PCX module. +

GPX XML (gpx)

This format can... -

  • +

    • read and write waypoints -

    • +

    • read and write tracks -

    • +

    • read and write routes -

    -

    This is the most capable and expressive of all the file +

This is the most capable and expressive of all the file formats supplied. It is described at topografix.com and is supported by EasyGPS, ExpertGPS, and many other programs described at topografix.com -

snlen option

+

+ GPSBabel's reader of this module attempts to preserve tags it doesn't + really understand. It also tries to glean interesting data from + pocket queries from Geocaching.com. +

snlen option

Length of generated shortnames. -

suppresswhite option

+

suppresswhite option

No whitespace in generated shortnames. -

logpoint option

+

logpoint option

Create waypoints from geocache log entries. -

urlbase option

+

urlbase option

Base URL for link tag in output. -

gpxver option

+

gpxver option

Target GPX version for output.

This option specifies the version of the GPX specification to use for @@ -1534,22 +1630,20 @@ Notice that this is not a full scale XML schema conversion. In particular, if you have a GPX 1.0 file that has extended namespaces in it (such as a pocket query from Geocaching.com) just writing it with this option will result in a horribly mangled GPX file as we can't convert the schema data. -

HikeTech (hiketech)

+

HikeTech (hiketech)

This format can... -

  • +

    • read and write waypoints -

    • +

    • read and write tracks -

    -

    This is the .gps format used by the Mac OS X applications +

This is the .gps format used by the Mac OS X applications written by HikeTech. These include TopoDraw, Link2GPS, and GPSWrite. More information about these products can be found at hiketech.com -

Holux (gm-100) .wpo Format (holux)

+

Holux (gm-100) .wpo Format (holux)

This format can... -

  • +

    • read and write waypoints -

    -

    The Holuxgm-100 (e-fox) gps receiver uses standard +

The Holux gm-100 (e-fox) gps receiver uses standard compact flash cards. File formats were provided by Holux-Taiwan holux.com to the author. The code was tested against version 2.27E1; other versions and @@ -1568,60 +1662,61 @@ loss is only about 1.7 meters (5 feet).

The generated waypoint failes can also be used by MapShow version 1.14. This program is free of charge from the Holux web site.

This format was contributed by Jochen Becker. -

HSA Endeavour Navigator export File (hsandv)

+

HSA Endeavour Navigator export File (hsandv)

This format can... -

  • +

    • read and write waypoints -

    -

    HSA Systems Endeavour Navigator format - will import both +

HSA Systems Endeavour Navigator format - will import both the old version 4.x binary files, and the newer XML based ones. Only writes the new XML (5.0 and above) format. (use the .exp -extension)

HTML Output (html)

+extension)

HTML Output (html)

This format can... -

  • +

    • write waypoints -

    -

    HTML output generates a single HTML file of all of the +

GPSBabel's HTML output generates a single HTML file of all of the waypoints in the input file. It supports a number of Groundspeak GPX -extensions, as well as filters out potentially harmful HTML from the -input file while maintaining almost all of the source HTML formatting. +extensions and filters out potentially harmful HTML from the +input file while maintaining almost all of the source HTML formatting. +This makes this format well suited for generating HTML to hand to programs +like Plucker for putting in a PDA and especially so for "paperless caching" +for Geocachers with pocket queries. +

This format is similar to the text format.

The following command line reads a GPX file with Groundspeak extensions and writes an HTML file with encrypted hints that is rendered using a custom stylesheet: -

gpsbabel -i gpx -f 12345.gpx -o html,stylesheet=green.css,encrypt -F 12345.html

stylesheet option

+

gpsbabel -i gpx -f 12345.gpx -o html,stylesheet=green.css,encrypt -F 12345.html

stylesheet option

Path to HTML style sheet.

Use this option to specify a CSS style sheet to be used with the resulting HTML file. -

encrypt option

+

encrypt option

Encrypt hints using ROT13.

Use this option to encrypt hints from Groundspeak GPX files. -

logs option

+

logs option

Include groundspeak logs if present.

Use this option to include Groundspeak cache logs in the created document. -

degformat option

+

degformat option

Degrees output as 'ddd', 'dmm'(default) or 'dms'.

When GPSBabel writes coordinates, this option is consulted to see if it should write decimal degrees ('ddd') decimal minutes ('dmm') or degrees, minutes, seconds ('dms'). The default is 'dmm'. -

altunits option

+

altunits option

Units for altitude (f)eet or (m)etres.

This option should be 'f' if you want the altitude expressed in feet and 'm' for meters. The default is 'f'. -

IGN Rando track files (ignrando)

+

IGN Rando track files (ignrando)

This format can... -

  • +

    • read and write tracks

    -

    This format supports IGN Rando track files. IGN Rando is a program mainly used in France for Topo maps. The files are XML based and are "windows-1252" encoded. Trackpoints do not have time stamps. -

    index option

    +

    index option

    Index of track to write (if more the one in source).

    Because the format supports only one track, this option may be used @@ -1629,107 +1724,125 @@ on output to select a single track from a collection of tracks read from a more expressive format. If you have, say, a gpx file that contains two tracks, you may use this option to write them one at a time to individual files. -

    gpsbabel -i gpx -f tracks.gpx -o ignrando,index=1 -F track1.txt -o ignrando,index=2 -F track2.txt

    Kartex 5 Track File (ktf2)

    +

    gpsbabel -i gpx -f tracks.gpx -o ignrando,index=1 -F track1.txt -o ignrando,index=2 -F track2.txt

Kartex 5 Track File (ktf2)

This format can... -

  • +

    • read and write waypoints

    -

    This format is derived from the xcsv format, so it has all of the same options as that format. -

    Support for Kartex 5 trackfiles. For more info see kwf2.

Kartex 5 Waypoint File (kwf2)

+

Support for Kartex 5 trackfiles. For more info see kwf2.

Kartex 5 Waypoint File (kwf2)

This format can... -

  • +

    • read and write waypoints

    -

    This format is derived from the xcsv format, so it has all of the same options as that format.

    Support for Kartex 5 waypoint files. Kartex is a Swedish map and GPS positioning system. GPSBabel can read and write files from Kartex 4 and 5 with WGS84 coordinates. UTM or Swedish grid are not supported. -

KuDaTa PsiTrex text (psitrex)

+

Kompass (DAV) Track (.tk) (kompass_tk)

+ This format can... +

  • + read and write tracks +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

+ This module supports track files used by Kompass and DAV "Deutscher Alpenverein". +

+ Kompass is a publishing company from Austria. + If you want to get more information about DAV, the German alpine association, + and if you are familiar with the german language, please have a look at their homepage. +

Kompass (DAV) Waypoints (.wp) (kompass_wp)

+ This format can... +

  • + read and write waypoints +

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

+ This module supports waypoint files used by Kompass and DAV "Deutscher Alpenverein". +

+ Some more information under kompass_tk format. +

KuDaTa PsiTrex text (psitrex)

This format can... -

  • +

    • read and write waypoints -

    • +

    • read and write tracks -

    • +

    • read and write routes -

    -

    This is a text format created by KuDaTa's PsiTrex program +

This is a text format created by KuDaTa's PsiTrex program for the Psion PDAs. The format can't be readily handled by XCSV, so this format is handled explicitly. Waypoints, routes and tracks are all handled, with icon names used corresponding to verison 1.13 of PsiTrex. This module was contributed to GPSBabel by Mark -Bradley.

Lowrance USR (lowranceusr)

+Bradley.

Lowrance USR (lowranceusr)

This format can... -

  • +

    • read and write waypoints -

    • +

    • read and write tracks -

    • +

    • read and write routes -

    -

    -The Lowrance iFinder GPS series has the unique capability +

+The Lowrance iFinder GPS series has the unique capability to output its data to an MMC card. The data is saved to the card as a .USR file and can be read by your computer using a card reader. Waypoints, routes, tracks are supported. By default, Event marker icons are converted to waypoints. Symbols tend to get lost in the translation. -

ignoreicons option

+

ignoreicons option

Ignore event marker icons.

This option instructs GPSBabel to not convert icons to waypoints on input. -

merge option

+

merge option

(USR output) Merge into one segmented track.

This option merges all tracks into a single track with multiple segments. -

break option

+

break option

(USR input) Break segments into separate tracks.

This option breaks track segments into separate tracks when reading a .USR file. -

Magellan Explorist Geocaching (maggeo)

+

Magellan Explorist Geocaching (maggeo)

This format can... -

  • +

    • write waypoints -

    -

    The SD card format used by the Magellan Explorist 400, -500, and 600 to describe geocaches. Notice what while the format can +

This format support the on-card format used by the Magellan Explorist 400, +Explorist 500, Explorist 600, Explorist 210, and Explorist XL +to describe geocaches. Notice what while the format can hold an infinite number of geocaches, the unit will read and silently discard all but 200 geocache POIs at a time.

You should name any file created with this format with a ".gs" extension so the firmware can read it. -

Magellan Mapsend (mapsend)

+

Magellan Mapsend (mapsend)

This format can... -

  • +

    • read and write waypoints -

    • +

    • read and write tracks -

    • +

    • read and write routes

    -

    -This format supports the Magellan MapSend™ native +This format supports the Magellan MapSend™ native file format.

    Kudos to Magellan for having the foresight to document their file formats, making software like this possible. -

    trkver option

    +

    trkver option

    MapSend version TRK file to generate (3,4).

    This option sets the MapSend version to generate TRK files, since new MapSend versions can't open version 3 files. Valid values are 3 (MapSend v3.0) or 4 (MapSend v4.0 and v4.1). -

    Magellan NAV Companion for Palm/OS (magnav)

    +

Magellan NAV Companion for Palm/OS (magnav)

This format can... -

  • +

    • read and write waypoints

    -

    -Magellan NAV Companion for Palm/OS is not really designed +Magellan NAV Companion for Palm/OS is not really designed for this sort of use, but its file format is supported and with a little bit of patience you can both read and write NAV Companion waypoints. This conversion is based on @@ -1752,7 +1865,7 @@ the old database, even in your backup directory. That's a feature of PalmOS, not of NAV Companion.)

    To merge the databases, use a command line like the following: -

    gpsbabel -i magnav -f Companion_Waypoints.PDB -i geo -f geocaching.loc -o magnav -F merged.pdb

    +

    gpsbabel -i magnav -f Companion_Waypoints.PDB -i geo -f geocaching.loc -o magnav -F merged.pdb

    Second, you must use the installer to install your new PDB file. Don't make the mistake of copying it over the existing Companion_Waypoints.PDB file; the one on the handheld will overwrite it rather than merging with @@ -1763,29 +1876,28 @@ applications, you must tell NAV Companion that its waypoints database has changed out from under it. One way to do this is to go to the waypoints screen and attempt to scroll; that will force it to reread the database and fix the record pointers that it keeps on the heap. -

Magellan SD files (as for eXplorist) (magellanx)

+

Magellan SD files (as for eXplorist) (magellanx)

This format can... -

  • +

    • read and write waypoints -

    • +

    • read and write tracks -

    • +

    • read and write routes

    -

    - This is the SD card format used by the Magellan Explorist 400, - 500, 600, and XL and internally on those devices plus the - Explorist 210. Waypoints are identical to the Magellan SD format - used by Meridian, but allows longer waypoint names. Routes are + This is the SD card format used by the Magellan Explorist 400, + Explorist 500, Explorist 600, and Explorist XL and internally on those devices plus the + Explorist 210. Stored waypoints are identical to the Magellan SD format + used by Meridian, but the newer models allow longer waypoint names. Routes are subtly different.

    You should name any file containing waypoints created with this format with a ".upt" extension so the firmware can read it. Similarly, routes should be named ".rte" and tracks should be named ".log". -

    deficon option

    +

    deficon option

    Default icon name. -

    maxcmts option

    +

    maxcmts option

    Max number of comments to write (maxcmts=200).

    The maxcmts option allows you to specify the number comments that will @@ -1798,30 +1910,30 @@ is therefore sometimes convenient to limit the number of waypoint comments written to the receiver. For example, a geocacher might want to upload 400 waypoints, but only 190 with comments so that DirectRoute could provide driving directions for the next ten turns. -

    Magellan SD files (as for Meridian) (magellan)

    +

Magellan SD files (as for Meridian) (magellan)

This format can... -

  • +

    • read and write waypoints -

    • +

    • read and write tracks -

    • +

    • read and write routes -

    -

    GPSBabel supports the following Magellan receivers: +

GPSBabel supports the following Magellan receivers:

310Meridian Color
315Explorist 100 (with aftermarket cable)
Map330Explorist 200 (with aftermarket cable)
SporTrak Map ColorExplorist 300 (with aftermarket cable)
SporTrak MapExplorist 210
SporTrak Map ProExplorist 300
SporTrak Map TopoExplorist 400
Meridian (green or yellow)Explorist 500
Meridian GoldExplorist 600
Meridian PlatinumExplorist XL

This format is used for both the serial protocol used on the devices with serial ports such as Map330 and Meridian and for the files stored either in either the unit's internal memory - (Explorist 210, 400, 500, 600, XL) or on removable memory. + (Explorist 210, Explorist 400, Explorist 500, Explorist 600, + Explorist XL) or on removable memory.

If you specify a serial port for the file (.e.g. "COM1", "/dev/ttyS0") to be read or written, GPSBabel will use serial protocol. Specifying a file, either on local filesystem or on a mounted flash card reader, will results in the file-based format being used. -

deficon option

+

deficon option

Default icon name. -

maxcmts option

+

maxcmts option

Max number of comments to write (maxcmts=200).

The maxcmts option allows you to specify the number comments that will @@ -1834,16 +1946,15 @@ is therefore sometimes convenient to limit the number of waypoint comments written to the receiver. For example, a geocacher might want to upload 400 waypoints, but only 190 with comments so that DirectRoute could provide driving directions for the next ten turns. -

Magellan serial protocol (magellan)

+

Magellan serial protocol (magellan)

This format can... -

  • +

    • read and write waypoints -

    • +

    • read and write tracks -

    • +

    • read and write routes -

    -

    GPSBabel supports the following Magellan receivers: +

GPSBabel supports the following Magellan receivers:

310Meridian Color
315Explorist 100 (with aftermarket cable)
Map330Explorist 200 (with aftermarket cable)
SporTrak Map ColorExplorist 300 (with aftermarket cable)
SporTrak MapExplorist 210
SporTrak Map ProExplorist 300
SporTrak Map TopoExplorist 400
Meridian (green or yellow)Explorist 500
Meridian GoldExplorist 600
Meridian PlatinumExplorist XL

The RoadMate family of products is not supported. @@ -1856,8 +1967,13 @@ The RoadMate family of products is not supported. If you specify a serial port for the file (.e.g. "COM1", "/dev/ttyS0") to be read or written, GPSBabel will use serial protocol. Specifying a file, either on local filesystem or on a mounted flash card reader, - will results in the file-based format being used. -

deficon option

+ will result in the file-based format being used. +

+ Users of the Explorist generation of receivers should probably + prefer to use the magellanx + format over this one. + +

deficon option

Default icon name.

This option specifies the icon or waypoint type to write for each waypoint on @@ -1868,7 +1984,7 @@ just those that do not already have descriptions. That is, this option overrides any icon description that might be in the input file.

This option has no effect on input. -

maxcmts option

+

maxcmts option

Max number of comments to write (maxcmts=200).

The maxcmts option allows you to specify the number comments that will @@ -1881,7 +1997,7 @@ is therefore sometimes convenient to limit the number of waypoint comments written to the receiver. For example, a geocacher might want to upload 400 waypoints, but only 190 with comments so that DirectRoute could provide driving directions for the next ten turns. -

baud option

+

baud option

Numeric value of bitrate (baud=4800).

This option causes GPSBabel to use the given baud rate for serial @@ -1889,7 +2005,7 @@ could provide driving directions for the next ten turns. default value matches the default on the receiver, 4800.

Valid options are 1200, 2400, 4800, 9600, 19200, 57600, and 115200. -

noack option

+

noack option

Suppress use of handshaking in name of speed.

Magellan's protocol specification strongly encourages the use of software @@ -1905,7 +2021,7 @@ In controlled environments (good cables, low electrical noise, receiving from the unit, not doing donuts with the unit set to "track up" at a 150 mile scale with 500 waypoints on the screen) it is sometimes useful to release that safety belt by using the "noack" suboption. -

nukewpt option

+

nukewpt option

Delete all waypoints.

This option erases all waypoints in the receiver before doing a transfer. @@ -1915,42 +2031,39 @@ to ensure the units starts with a clean state before sending waypoints to it. Using this option on transmit is a better idea than doing it on receive since the latter would erase all the waypoints before asking the unit to send all the waypoints. -

Map&Guide 'TourExchangeFormat' XML (tef)

+

Map&Guide 'TourExchangeFormat' XML (tef)

This format can... -

  • +

    • read routes

    -

    TEF, internally called "TourExchangeFormat", is an XML based export format used by Map&Guide Motorrad-Routenplaner 2005/06™.

    Because this is only an export format, GPSBabel does not support writing to this format.

    -GPSBabel also supports the bcr format, which +GPSBabel also supports the bcr format, which may also be used with this program and supports both reading and writing. -

     gpsbabel -r -i tef,routevia -f in.xml -o gpx -F out.gpx

    routevia option

    +

    gpsbabel -r -i tef,routevia -f in.xml -o gpx -F out.gpx

    routevia option

    Include only via stations in route.

    This option may be used to eliminate calculated route points from the route. -

    Map&Guide to Palm/OS exported files (.pdb) (mag_pdb)

    +

Map&Guide to Palm/OS exported files (.pdb) (mag_pdb)

This format can... -

  • +

    • read waypoints -

    • +

    • read routes -

    -

    With this format we support the Palm/OS export for +

With this format we support the Palm/OS export for Map&Guide based products like "PowerRoute", "Motorrad-Routenplaner" and (maybe) other software. The exported files can contain maps and/or route descriptions. The reader for this format has been tested with PowerRoute 5+6, Motorrad-Routenplaner -2002(-2006).

Mapopolis.com Mapconverter CSV (mapconverter)

+2002(-2006).

Mapopolis.com Mapconverter CSV (mapconverter)

This format can... -

  • +

    • read and write waypoints

    -

    This format is derived from the xcsv format, so it has all of the same options as that format.

    @@ -1965,7 +2078,7 @@ accept. The steps for using GPSBabel and Mapconverter go something like this:

    Step 1: Create a mapconverter file using gpsbabel. -

    gpsbabel -i geo -f geocaching.loc -o mapconverter -F foo.txt

    +

    gpsbabel -i geo -f geocaching.loc -o mapconverter -F foo.txt

    Step 2: Launch mapconverter.exe and choose foo.txt as your input file. Click the begin button to have mapconverter process foo.txt.

    @@ -1989,23 +2102,21 @@ Mapconverter is no longer available from the Mapopolis website. If you need a copy of mapconverter, ask on your local GPS Software discussion forum and I'm sure someone will have it. As far as I know, It was never actually acknowledged/supported by Mapopolis to begin with. -

MapTech Exchange Format (mxf)

+

MapTech Exchange Format (mxf)

This format can... -

  • +

    • read and write waypoints

    -

    This format is derived from the xcsv format, so it has all of the same options as that format.

    Maptech Exchange Format - Another CSV format file. This format complies with (at least) Maptech Terrain Navigator, Terrain Professional, Take a Hike, and ExpertGPS import/export MFX. -Contributed by Alex Mottram.

Microsoft AutoRoute 2002 (pin/route reader) (msroute)

+Contributed by Alex Mottram.

Microsoft AutoRoute 2002 (pin/route reader) (msroute)

This format can... -

  • +

    • read routes -

    -

    Input support for Microsoft AutoRoute 2002-2006 .axe files +

Input support for Microsoft AutoRoute 2002-2006 .axe files and Microsoft Streets and Trips .est files. These files contains only routes. We can extract the coordinates and the names of the points within route. An export to this format will @@ -2018,12 +2129,11 @@ use the Streets and Trips drawing tools to trace a line over the interesting parts of the route to capture intersections or key turns. GPSBabel will capture stops in the route and insert those as turns, so adding stops at intersections can also improve the results when converting. -

Microsoft Streets and Trips (pin/route reader) (msroute)

+

Microsoft Streets and Trips (pin/route reader) (msroute)

This format can... -

  • +

    • read routes -

    -

    Input support for Microsoft AutoRoute 2002-2006 .axe files +

Input support for Microsoft AutoRoute 2002-2006 .axe files and Microsoft Streets and Trips .est files. These files contains only routes. We can extract the coordinates and the names of the points within route. An export to this format will @@ -2036,28 +2146,27 @@ use the Streets and Trips drawing tools to trace a line over the interesting parts of the route to capture intersections or key turns. GPSBabel will capture stops in the route and insert those as turns, so adding stops at intersections can also improve the results when converting. -

Microsoft Streets and Trips 2002-2006 (s_and_t)

+

Microsoft Streets and Trips 2002-2006 (s_and_t)

This format can... -

  • +

    • read and write waypoints

    -

    This format is derived from the xcsv format, so it has all of the same options as that format. -

    This is a format for importing into Microsoft Streets and -Trips. It's been exercised on versions 2003, 2004, and 2005. Detailed +

    This is a format for importing into + Microsoft Streets and +Trips. It's been exercised on versions from 2003 through 2007. Detailed instructions on how to use it, including preserving hyperlinks, are at gpsbabel.org -

Motorrad Routenplaner (Map&Guide) .bcr files (bcr)

+

Motorrad Routenplaner (Map&Guide) .bcr files (bcr)

This format can... -

  • +

    • read and write routes -

    -

    +

This file format (extension .bcr) is used in Map&Guide Motorrad Routenplaner 2002™ and later versions. BCR is a route-only format. If you own a newer release (2005 or later) you -may also use the XML export with GPSBabel's tef +may also use the XML export with GPSBabel's tef input format.

There may be other products from Map&Guide that use this format as well. @@ -2066,7 +2175,7 @@ Coordinates are stored in a BCR file in a Mercator projection. The conversion from the Mercator projection to polar (latitude/longitude) coordinates and back again may result in visible differences. Experience reports are welcome. -

Example 3.2. Sample BCR command with all options

gpsbabel -r -i gpx -f in.gpx -o bcr,index=1,name="From A to B",radius=6371012 -F a_to_b.bcr

index option

+

Example 3.2. Sample BCR command with all options

gpsbabel -r -i gpx -f in.gpx -o bcr,index=1,name="From A to B",radius=6371012 -F a_to_b.bcr


index option

Index of route to write (if more the one in source).

Because the format supports only one route, this option may be used @@ -2074,13 +2183,13 @@ on output to select a single route from a collection of routes read from a more expressive format. If you have, say, a gpx file that contains two routes, you may use this option to write them one at a time to individual files. -

gpsbabel -i gpx -f routes.gpx -o bcr,index=1 -F route1.bcr -o bcr,index=2 -F route2.bcr

name option

+

gpsbabel -i gpx -f routes.gpx -o bcr,index=1 -F route1.bcr -o bcr,index=2 -F route2.bcr

name option

New name for the route.

This route specifies the name of the route. This is particularly useful if the route came from an input format that did not support named routes, but it may also be used to rename a route. -

radius option

+

radius option

Radius of our big earth (default 6371000 meters).

This option instructs GPSBabel to use a different value for the radius of @@ -2089,12 +2198,16 @@ coordinates. The default value is 6371000.0 meters.

Careful experimentation with this value may help to reduce conversion errors. -

MS PocketStreets 2002 Pushpin (psp)

+

prefer_shortnames option

+ Use shortname instead of description. +

+This option causes GPSBabel to use the short name of the waypoint instead +of the description. +

MS PocketStreets 2002 Pushpin (psp)

This format can... -

  • +

    • read and write waypoints

    -

    Microsoft's PocketStreets 2002 Pushpin (.PSP) format is not yet completely documented. The .PSP module does not work with MS Streets & Trips 2002 .EST files To create .PSP files from @@ -2110,40 +2223,40 @@ outside of the exported map area, the pin will be "grayed-out" and unused in PocketStreets. This is a good thing as it allows us to create one big .PSP file that covers multiple .MPS files. Unfortunately, you need one .PSP file for every .MPS file. -

    Frequently Asked Questions

    1. +

    Frequently Asked Questions

    1. Why should I use GPSBabel/psp to make pushpins when Streets & Trips (S&T) already does that for me? -
    2. +
    2. I keep getting a blank (32 byte) PSP file. -
    3. +
    3. I've created a PSP file, now what do I do with it? -
    4. +
    4. I don't have a map. What do I do now? -
    5. +
    5. I have .EST files, not .PSP files. What's up with that? -
    6. +
    6. The .PSP files differ when I use GPSBabel/psp versus Pocketstreets to create them. What's up? -
    7. +
    7. Does GPSBabel/psp work with (Autoroute, Mappoint, etc..) .PSP files? -
    8. +
    8. Does GPSBabel/psp work with (S&T 2001, S&T 2002, etc...) files? -
    9. +
    9. Does GPSBabel/psp work with (insert your country/location here) maps? -
    10. +
    10. What do you mean S&T writes points with the wrong coordinates? -
    11. +
    11. I have 800 waypoints that cover a dozen or so Pocketstreets maps. Do I need to to split my points up into smaller chunks to match the area covered by the maps? -
    12. +
    12. Where can I find documentation for the layout of PSP files? -
    13. +
    13. I have some other problem, what do I do? -
    1.

    +
    1.

    Why should I use GPSBabel/psp to make pushpins when Streets & Trips (S&T) already does that for me? -

    +

    GPSBabel/psp has the advantage of being able to create pushpins without creating the associated map file and the need to "import" the waypoint @@ -2155,139 +2268,135 @@ GPSBabel/psp has the advantage of being able to create pushpins with the proper coordinates where S&T does not in some areas of the U.S. (Nashville, TN for instance). -

    2.

    +

    2.

    I keep getting a blank (32 byte) PSP file. -

    +

    There are either no points to write, or you have botched the command line for GPSBabel. GPSBabel is sensitive to UPPER and lower case on the command line. A simple command line to create PSP files looks like this: -

    gpsbabel -i geo -f geocaching.loc -o psp -F NewOrleans.psp

    +

    gpsbabel -i geo -f geocaching.loc -o psp -F NewOrleans.psp

    Note the use of "-f" for INPUT files and "-F" for OUTPUT files. -

    3.

    +

    3.

    I've created a PSP file, now what do I do with it? -

    +

    To use pushpins in Pocketstreets, you need to have both a map and a pushpin file. These two files must exist in the same folder and have exactly the same base name as the map. For example, the pins that correspond to the map "NewOrleans.mps" should be named "NewOrleans.psp". -

    4.

    +

    4.

    I don't have a map. What do I do now? -

    +

    Create one using the "Export map to Pocketstreets" option in S&T. You can also pick up some major city maps on the web from the MS Pocketstreets website if you are interested in seeing how it works. -

    5.

    +

    5.

    I have .EST files, not .PSP files. What's up with that? -

    +

    In order to make PSP files, you need to use the "Export map to Pocketstreets" function in S&T. .EST files are for use in S&T, not Pocketstreets. -

    6.

    +

    6.

    The .PSP files differ when I use GPSBabel/psp versus Pocketstreets to create them. What's up? -

    +

    Pocketstreets makes corrections to the S&T waypoint data upon initial loading. GPSBabel/psp writes PSP files with these corrections already made. Ask MS. -

    7.

    +

    7.

    Does GPSBabel/psp work with (Autoroute, Mappoint, etc..) .PSP files? -

    +

    As of this writing, I haven't seen any so I can't be sure. If they follow the same layout as S&T 2002, I'd imagine so. -

    8.

    +

    8.

    Does GPSBabel/psp work with (S&T 2001, S&T 2002, etc...) files? -

    +

    MS changed the file layout between S&T 2001 and S&T 2002. The GPSBabel psp module is known to work fine with S&T 2002 and 2003. -

    9.

    +

    9.

    Does GPSBabel/psp work with (insert your country/location here) maps? -

    +

    If it doesn't, feel free to inquire on the GPSBabel-Misc mailing list. -

    10.

    +

    10.

    What do you mean S&T writes points with the wrong coordinates? -

    +

    At some point in the "Export map to Pocketstreets" function in S&T, it goofs the lat/long data. Points in Nashville tended to shift 1.4 miles WEST of their original location. I'm not a geometry buff, but I'd imagine they have a reference point for generating coordinates that's wrong in (at least) that area. -

    11.

    +

    11.

    I have 800 waypoints that cover a dozen or so Pocketstreets maps. Do I need to to split my points up into smaller chunks to match the area covered by the maps? -

    +

    No. Pocketstreets will "ignore" points that are outside of the map area. Points that are not on the current map will be "grayed out" in pushpin explorer in Pocketsreets. This is the reason the PSP module was written for GPSBabel in the first place. -

    12.

    +

    12.

    Where can I find documentation for the layout of PSP files? -

    +

    Just about everything I know about the PSP file format is documented in the source. To the best of my knowledge, there is no documentation (and for good reason, I've come to discover). -

    13.

    +

    13.

    I have some other problem, what do I do? -

    +

    Ask your question on the GPSBabel-Misc mailing list. -

    National Geographic Topo .tpg (waypoints) (tpg)

    +

    National Geographic Topo .tpg (waypoints) (tpg)

    This format can... -

    • +

      • read and write waypoints -

      -

      National Geographic Topo! Waypoint and Route Format. This module +

    National Geographic Topo! Waypoint and Route Format. This module reads and writes .TPG files created by various editions of NG Topo! -Reading/writing of route data is not supported yet.

    Contributed by Alex Mottram.

    datum option

    +Reading/writing of route data is not supported yet.

    Contributed by Alex Mottram.

    datum option

    Datum (default=NAD27).

    The option 'datum="datum name"' can be used to override the default of NAD27 ("N. America 1927 mean") which is correct for the -continental U.S. Points in Hawaii should use "Old -Hawaiian_mean"

    National Geographic Topo 2.x .tpo (tpo2)

    +continental U.S.

    Any legal datum supported +by GPSBabel may be used. For example, points in Hawaii should +use "Old Hawaiian_mean".

    National Geographic Topo 2.x .tpo (tpo2)

    This format can... -

    • +

      • read tracks

      -

      This module reads tracks from .TPO files created by National Geographic Topo! version 2.x

      Contributed by Steve Chamberlin. -

    National Geographic Topo 3.x/4.x .tpo (tpo3)

    +

    National Geographic Topo 3.x/4.x .tpo (tpo3)

    This format can... -

    • +

      • read waypoints -

      • +

      • read tracks -

      • +

      • read routes -

      -

      This module reads .TPO files created by National Geographic Topo! version +

    This module reads .TPO files created by National Geographic Topo! version 3.x and 4.x. It will read tracks, routes, waypoints, map notes, symbols, and -text notes. The latter three are converted to waypoints.

    Contributed by Curt Mills.

    Navicache.com XML (navicache)

    +text notes. The latter three are converted to waypoints.

    Contributed by Curt Mills.

    Navicache.com XML (navicache)

    This format can... -

    • +

      • read waypoints -

      -

      This is the XML format that's used by Navicache.com for +

    This is the XML format that's used by Navicache.com for their geocaching data. There are a number of fields in it that are marked "required" but are Navicache-specific, so GPSBabel can not write these files, but we can still read them. navicache.com -

    noretired option

    +

    noretired option

    Suppress retired geocaches. -

    Navigon Mobile Navigator .rte files (nmn4)

    +

    Navigon Mobile Navigator .rte files (nmn4)

    This format can... -

    • +

      • read and write routes -

      -

      Support for Navigon Mobile Navigator route (.rte) files. +

    Support for Navigon Mobile Navigator route (.rte) files. This is a very simple text format that only requires coordinates, but has fields for many other things. We only write coordinates as fields like 'city' and 'street' cannot typically be populated from other formats. www.navigon.com -

    index option

    +

    index option

    Index of route to write (if more the one in source).

    Because the format supports only one route, this option may be used @@ -2295,23 +2404,21 @@ on output to select a single route from a collection of routes read from a more expressive format. If you have, say, a gpx file that contains two routes, you may use this option to write them one at a time to individual files. -

    gpsbabel -i gpx -f routes.gpx -o nmn4,index=1 -F route1.rte -o nmn4,index=2 -F route2.rte

    Navitrak DNA marker format (dna)

    +

    gpsbabel -i gpx -f routes.gpx -o nmn4,index=1 -F route1.rte -o nmn4,index=2 -F route2.rte

    Navitrak DNA marker format (dna)

    This format can... -

    • +

      • read and write waypoints

      -

      This format is derived from the xcsv format, so it has all of the same options as that format.

      Navitrak DNA marker format - Another CSV format file. This is the format that is compatible with the DNA Desktop import/export command. Reading the binary Markers.jwp format directly off the data -card is not supported yet. Contributed by Tim Zickus.

    NetStumbler Summary File (text) (netstumbler)

    +card is not supported yet. Contributed by Tim Zickus.

    NetStumbler Summary File (text) (netstumbler)

    This format can... -

    • +

      • read waypoints

      -

      This format reads summary files from NetStumbler™ 0.4 or MacStumbler™.

      @@ -2327,76 +2434,88 @@ changed with options. NetStumbler

      MacStumbler -

      nseicon option

      +

      nseicon option

      Non-stealth encrypted icon name.

      This option specifies the name of the icon to use for non-stealth, encrypted access points. -

      nsneicon option

      +

      nsneicon option

      Non-stealth non-encrypted icon name.

      This option specifies the name of the icon to use for non-stealth, non-encrypted access points. -

      seicon option

      +

      seicon option

      Stealth encrypted icon name.

      This option specifies the name of the icon to use for stealth, encrypted access points. -

      sneicon option

      +

      sneicon option

      Stealth non-encrypted icon name.

      This option specifies the name of the icon to use for stealth, non-encrypted access points. -

      snmac option

      +

      snmac option

      Shortname is MAC address.

      This option causes GPSBabel to use the MAC address as the short name for the waypoint. The unmodified SSID is included in the waypoint description. -

      NIMA/GNIS Geographic Names File (nima)

      +

    NIMA/GNIS Geographic Names File (nima)

    This format can... -

    • +

      • read and write waypoints

      -

      This format is derived from the xcsv format, so it has all of the same options as that format.

      This is a CSV format from the National Imagery and Mapping -Agency.

    NMEA 0183 sentences (nmea)

    +Agency.

    NMEA 0183 sentences (nmea)

    This format can... -

    • +

      • read and write waypoints -

      • +

      • read and write tracks -

      -

      This format is the file representation of the NMEA +

    This format is the file representation of the NMEA (National Marine Electronics Association) 0183 log and waypoint format for GPS devices. Some hardware and software that work with NMEA-0183 formatted data include:

    GPS Data Logger - NMEAlog + VisualGPS - GeoConv + SparkFun GPS Datalogger
    GPS TrackMaker - VisualGPS + GPS Utility - CommLinx GPS recorder + Sony GPS-CS1
    GPSMaster - GPS Utility + GeoConv + 
    + NMEAlog - SparkFun GPS Datalogger -

    snlen option

    + CommLinx GPS recorder + 

    +This module also supports realtime tracking +which allows realtime position reports from a GPS, such as one connected +serially, over Bluetooth, or a USB module emulating a serial port, to be used +with selected output formats. +

    +When used in realtime tracking mode, if +GPSBabel does not sense incoming NMEA sentences arriving from the port, it +will send Sirf "reset to NMEA" commands to the port at a variety of speeds +in an attempt to communicate with an attached GPS. This lets devices +like the Microsoft GPS or Pharos GPS that are Sirf chips with an integrated +USB/Serial adapter work with this input format. +

    snlen option

    Max length of waypoint name to write.

    This option specifies the maximum length to be used for waypoint names in the GPWPL sentence. Longer names will be shortened to no more than this length, but all waypoint names will remain unique. -

    gprmc option

    +

    gprmc option

    Read/write GPRMC sentences.

    This option tells GPSBabel whether to read (on input) or write (on output) @@ -2406,7 +2525,7 @@ disable GPRMC sentences, specify gprmc=0. GPRMC sentences contain the "recommended mimimum" positional information, including date and time, heading, and velocity. Note that they do not include altitude. For altitude, you will have to include GPGGA sentences. -

    gpgga option

    +

    gpgga option

    Read/write GPGGA sentences.

    This option tells GPSBabel whether to read (on input) or write (on output) @@ -2414,7 +2533,7 @@ GPGGA sentences. The default is to read or write GPGGA sentences. To disable GPGGA sentences, specify gpgga=0.

    GPGGA sentences contain the location and quality of the GPS position fix. -

    gpvtg option

    +

    gpvtg option

    Read/write GPVTG sentences.

    This option tells GPSBabel whether to read (on input) or write (on output) @@ -2424,7 +2543,7 @@ disable GPVTG sentences, specify gpvtg=0. GPVTG sentences contain information about the heading and the speed at the time of the fix. They do not contain any location information; for that you will need either or both of GPGGA or GPRMC. -

    gpgsa option

    +

    gpgsa option

    Read/write GPGSA sentences.

    This option tells GPSBabel whether to read (on input) or write (on output) @@ -2435,7 +2554,7 @@ GPGSA sentences contain information on the quality of the positional fix and the individual satellites from which it was derived. However, GPSBabel neither reads nor writes the individual satellite data. On input, the satellite fields are ignored and on output they are left blank. -

    date option

    +

    date option

    Complete date-free tracks with given date (YYYYMMDD)..

    On input, track points with times but no dates will have this date applied. @@ -2443,11 +2562,11 @@ On input, track points with times but no dates will have this date applied. This is necessary because some NMEA sentences contain times but no dates. If this option is not specified and the date cannot be determined from one or more of the available NMEA sentences, the tracks will be discarded. -

    get_posn option

    +

    get_posn option

    Return current position as a waypoint.

    This options, when specified, returns the current position as a single waypoint. -

    pause option

    +

    pause option

    Decimal seconds to pause between groups of strings.

    This option tells GPSBabel to pause between individual track records when @@ -2474,40 +2593,38 @@ be as much as plus or minus 100 milliseconds. If you are using this option with compressed or simplified tracks from your handheld GPS receiver, you might find the interpolate filter useful. -

    baud option

    +

    baud option

    Speed in bits per second of serial port (baud=4800).

    To the "nmea" module, the "baud" option specifies the baud rate of the serial connection when used with the real-time tracking option. -

    OziExplorer (ozi)

    +

    OziExplorer (ozi)

    This format can... -

    • +

      • read and write waypoints -

      • +

      • read and write tracks -

      • +

      • read and write routes -

      -

      OziExplorer Waypoint Format - Another CSV format file. +

    OziExplorer Waypoint Format - Another CSV format file. Tested against OziExplorer v 3.90.3a / Shareware. Contributed by Alex -Mottram

    snlen option

    +Mottram

    snlen option

    Max synthesized shortname length. -

    snwhite option

    +

    snwhite option

    Allow whitespace synth. shortnames. -

    snupper option

    +

    snupper option

    UPPERCASE synth. shortnames. -

    snunique option

    +

    snunique option

    Make synth. shortnames unique. -

    wptfgcolor option

    +

    wptfgcolor option

    Waypoint foreground color. -

    wptbgcolor option

    +

    wptbgcolor option

    Waypoint background color. -

    PalmDoc Output (palmdoc)

    +

    PalmDoc Output (palmdoc)

    This format can... -

    • +

      • write waypoints -

      -

      +

    PalmDoc output is similar to Text output, except that it generates a Palm Database (PDB) file suitable for use with programs like CSpotRun, TealDoc, AportisDoc, Palm Reader, and @@ -2516,25 +2633,25 @@ to a particular waypoint.

    The following command line reads a GPX file with Groundspeak extensions and writes a Palm document with encrypted hints and logs: -

    gpsbabel -i gpx -f 12345.gpx -o "palmdoc,dbname=Unfound Geocaches,encrypt,logs" -F 12345.pdb

    nosep option

    +

    gpsbabel -i gpx -f 12345.gpx -o "palmdoc,dbname=Unfound Geocaches,encrypt,logs" -F 12345.pdb

    nosep option

    No separator lines between waypoints.

    To suppress the dashed lines between waypoints, use this option. -

    dbname option

    +

    dbname option

    Database name.

    This option specifies the internal name for the document. This is the name that appears in your document reader, not the name of the file that is created on your computer. -

    encrypt option

    +

    encrypt option

    Encrypt hints with ROT13.

    Use this option to encrypt hints from Groundspeak GPX files. -

    logs option

    +

    logs option

    Include groundspeak logs if present.

    Use this option to include Groundspeak cache logs in the created document. -

    bookmarks_short option

    +

    bookmarks_short option

    Include short name in bookmarks.

    If you would like the generated bookmarks to start with @@ -2542,41 +2659,39 @@ the short name for the waypoint, specify this option.

    This is particularly useful when used in combination with the 'sort' filter. -

    PathAway Database for Palm/OS (pathaway)

    +

    PathAway Database for Palm/OS (pathaway)

    This format can... -

    • +

      • read and write waypoints -

      • +

      • read and write tracks -

      • +

      • read and write routes -

      -

      PathAway is a Palm software designed for handling "most" +

    PathAway is a Palm software designed for handling "most" GPS devices (including BlueTooth). In this time (I mean 2005) a free tool to convert this database is located on the homepage of PathAway (www.pathaway.com). But I've read there ... for windows and the output formats are also very limited. -

    date option

    +

    date option

    Read/Write date format (i.e. DDMMYYYY).

    This option specifies the input and output format for the date. The format is written similarly to those in Windows. An example format is "YYMMDD". -

    dbname option

    +

    dbname option

    Database name.

    This option specifies the database name for the output file. This name is not the same thing as the file name on your computer; this is the name that appears in the file browser on your handheld. -

    deficon option

    +

    deficon option

    Default icon name. -

    snlen option

    +

    snlen option

    Length of generated shortnames. -

    Quovadis (quovadis)

    +

    Quovadis (quovadis)

    This format can... -

    • +

      • read and write waypoints -

      -

      QuoVadis for Palm OS marcosoft.com is a program for +

    QuoVadis for Palm OS marcosoft.com is a program for Palm/OS. Working with record definitions provided by MarcoSoft and further experimentation by Bruce Thompson and "Fuzzy" from the Geocaching Forums to nail down the format precisely.

    Should work fine for import and export.

    One thing of note, QuoVadis stores all waypoints in a @@ -2589,18 +2704,30 @@ joining capabilities generate a new PDB file from the personal file and the other waypoint files of interest.

    Currently the selection of icons to display and the scale at which to display them is hardcoded. Also there is no support for notes associated with waypoints. This will be addressed in a future -revision.

    dbname option

    +revision.

    dbname option

    Database name.

    This option specifies the database name for the output file. This name is not the same thing as the file name on your computer; this is the name that appears in the file browser on your handheld. -

    See You flight analysis data (cup)

    +

    Raymarine Waypoint File (.rwf) (raymarine)

    This format can... -

    • +

      • + read and write waypoints +

      • + read and write routes +

      + This format supports the "Raymarine Waypoint File" format (.rwf). + More information to Raymarine you'll find at their homepage. +

      + Known limits: max. 16 characters for waypoint names and max. 50 waypoints per route. +

      location option

      + Default location. +

    See You flight analysis data (cup)

    + This format can... +

    • read and write waypoints

    -

    This format is derived from the xcsv format, so it has all of the same options as that format.

    @@ -2613,12 +2740,11 @@ format, so it has all of the same options as that format. written as blanks and ignored on read.

    Tasks are not supported. -

    Sportsim track files (part of zipped .ssz files) (sportsim)

    +

    Sportsim track files (part of zipped .ssz files) (sportsim)

    This format can... -

    • +

      • read and write waypoints

      -

      This format is derived from the xcsv format, so it has all of the same options as that format.

      @@ -2631,14 +2757,13 @@ format, so it has all of the same options as that format.

      Sportsim provide software applications and web-based graphically simulated performance information and image solutions to outdoor active people. -

    Suunto Trek Manager (STM) .sdf files (stmsdf)

    +

    Suunto Trek Manager (STM) .sdf files (stmsdf)

    This format can... -

    • +

      • read and write tracks -

      • +

      • read and write routes

      -

      This format supports the .sdf files from the Suunto product family 'Suunto Trek Manager', 'Suunto Ski Manager' and 'Suunto Sail Manager'. The contents of the sdf file depends on the used product and can @@ -2649,11 +2774,9 @@ format, so it has all of the same options as that format.

      Currently we can read the following file types:

      4 = M9 TrackLog
      5 = Route
      28 = X9 TrackLog

      -

      -

      gpsbabel -i gpx -f some-routes.gpx -r -o stmsdf,index=3 -F single-route.sdf

      -

      +

      gpsbabel -i gpx -f some-routes.gpx -r -o stmsdf,index=3 -F single-route.sdf

      Suunto Website -

      index option

      +

      index option

      Index of route (if more the one in source).

      Convert route number 'index' from source into sdf format. @@ -2665,26 +2788,22 @@ format, so it has all of the same options as that format. Our default index is 1.

      This example will convert route number two and three into separate sdf files: -

      -		gpsbabel -i gdb -f routes.gdb -r -o stmsdf,index=2 -F route-one.sdf -r -o stmsdf,index=3 -F route-three.sdf
      -	

      -

      Suunto Trek Manager (STM) WaypointPlus files (stmwpp)

      +

      gpsbabel -i gdb -f routes.gdb -r -o stmsdf,index=2 -F route-one.sdf -r -o stmsdf,index=3 -F route-three.sdf

    Suunto Trek Manager (STM) WaypointPlus files (stmwpp)

    This format can... -

    • +

      • read and write waypoints -

      • +

      • read and write tracks -

      • +

      • read and write routes

      -

      This format supports the Suunto Trek Manager (STM) WaypointPlus format. This is a simple format with coordinates and a time stamp. Route points also have a short name. A single file may only contain one route or one track.

      Suunto Website -

      index option

      +

      index option

      Index of route/track to write (if more the one in source).

      Because the format supports only one route or track, this option may be used @@ -2692,58 +2811,55 @@ on output to select a single route or track from a collection of routes and tracks read from a more expressive format. If you have, say, a gpx file that contains three routes, you may use this option to write them one at a time to individual files. -

      gpsbabel -i gpx -f routes.gpx -o stmwpp,index=1 -F route1.txt -o stmwpp,index=2 -F route2.txt -o stmwpp,index=3 -F route3.txt

      Tab delimited fields useful for OpenOffice, Ploticus etc. (openoffice)

      +

      gpsbabel -i gpx -f routes.gpx -o stmwpp,index=1 -F route1.txt -o stmwpp,index=2 -F route2.txt -o stmwpp,index=3 -F route3.txt

    Tab delimited fields useful for OpenOffice, Ploticus etc. (openoffice)

    This format can... -

    • +

      • read and write waypoints

      -

      This format is derived from the xcsv format, so it has all of the same options as that format.

      Tab seperated export-all (except geocaching data) file format. Intended to serve as source for number-processing applications like OpenOffice, Ploticus and others. Tab was chosen as delimiter because it is a) supported by both OpenOffice and Ploticus -and b) is not ',', so you can use sed -i -"s/./,/g" <x>.csv' to adapt it to locales where ',' is -used as decimal seperator. Contributed by Tobias Minich.

    Textual Output (text)

    +and b) is not ',', so you can use sed -i +"s/./,/g" <x>.csv' to adapt it to locales where ',' is +used as decimal seperator. Contributed by Tobias Minich.

    Textual Output (text)

    This format can... -

    • +

      • write waypoints -

      -

      This is a simple human readable version of the data file, +

    This is a simple human readable version of the data file, handy for listings of any type of waypoint files.

    The following command line reads a GPX file with Groundspeak extensions and writes a text file with encrypted hints: -

    gpsbabel -i gpx -f 12345.gpx -o text,encrypt -F 12345.txt

    nosep option

    +

    gpsbabel -i gpx -f 12345.gpx -o text,encrypt -F 12345.txt

    nosep option

    Suppress separator lines between waypoints.

    To suppress the dashed lines between waypoints, use this option. -

    encrypt option

    +

    encrypt option

    Encrypt hints using ROT13.

    Use this option to encrypt hints from Groundspeak GPX files. -

    logs option

    +

    logs option

    Include groundspeak logs if present.

    Use this option to include Groundspeak cache logs in the created document. -

    degformat option

    +

    degformat option

    Degrees output as 'ddd', 'dmm'(default) or 'dms'.

    When GPSBabel writes coordinates, this option is consulted to see if it should write decimal degrees ('ddd') decimal minutes ('dmm') or degrees, minutes, seconds ('dms'). The default is 'dmm'. -

    altunits option

    +

    altunits option

    Units for altitude (f)eet or (m)etres.

    This option should be 'f' if you want the altitude expressed in feet and 'm' for meters. The default is 'f'. -

    TomTom POI file (tomtom)

    +

    TomTom POI file (tomtom)

    This format can... -

    • +

      • read and write waypoints -

      -

      This format can read and write TomTom .ov2 (POI) files, +

    This format can read and write TomTom .ov2 (POI) files, as used by the TomTom GO and TomTom Navigator. It has been tested with an original TomTom GO running version 5.00 of the TomTom software. There may be some records that confuse the input module - @@ -2752,24 +2868,22 @@ restricted from sharing it, we encourage you to post to the gpsbabel-misc mailing list to contact a developer.

    Note that in addition to the .ov2 file, you will need a .bmp file for the icon. It should be 22x22 and 16 colors, and have the same name (not including the extension) as the .ov2 file. -

    TopoMapPro Places File (tmpro)

    +

    TopoMapPro Places File (tmpro)

    This format can... -

    • +

      • read and write waypoints -

      -

      TopoMapPro Places File. Reads and writes places files for -use in TopoMapPro topomappro.com). As this file +

    Reads and writes places files for +use in TopoMapPro places files. As this file type can store links other than web links, anything that is not a http url will be discarded. Note that this does not do datum conversions, so if your input file does not have WGS84/NZGD2000 data, your output -file won't either. Colour of waypoint icons defaults to red.

    TrackLogs digital mapping (.trl) (dmtlog)

    +file won't either. Colour of waypoint icons defaults to red.

    TrackLogs digital mapping (.trl) (dmtlog)

    This format can... -

    • +

      • read and write waypoints -

      • +

      • read and write tracks

      -

      This format can be used to convert files from TrackLogs Digital Mapping. The files have extension .trl and can contain waypoints and tracks. @@ -2777,7 +2891,7 @@ file won't either. Colour of waypoint icons defaults to red.

    index option

    +

    index option

    Index of track (if more the one in source).

    Convert track number 'index' from source into dmtlog format. @@ -2791,20 +2905,19 @@ file won't either. Colour of waypoint icons defaults to red.

    An example usage you can find at the ignrando format, which uses option index in same manner. -

    U.S. Census Bureau Tiger Mapping Service (tiger)

    +

    U.S. Census Bureau Tiger Mapping Service (tiger)

    This format can... -

    • +

      • read and write waypoints -

      -

      The U.S. Census Bureau provides online mapping facilities. +

    The U.S. Census Bureau provides online mapping facilities. This format is described at: tiger.census.gov. Do notice that this format is not the actual Tiger line mapping records, but rather the interface to their online mapping -program.

    nolabels option

    +program.

    nolabels option

    Suppress labels on generated pins.

    This option tells GPSBabel to not generate labels on the pins. If this is true, the description of the incoming waypoints are ignored and not -placed on the pins.

    genurl option

    +placed on the pins.

    genurl option

    Generate file with lat/lon for centering map.

    genurl is a convenience option for generating the scaling paramaters @@ -2812,66 +2925,65 @@ when accessing the Tiger servers. It will output the latitude, longitude, height, and width parameters in a form suitable for use in the URL to generate a map that will hold all the points to be displayed and is suitably scaled and centered. -

    For example: -

    gpsbabel -i geo -f geocaching.loc -o tiger,genurl=tiger.ctr -F tiger.dat

    +

    For example:

    gpsbabel -i geo -f geocaching.loc -o tiger,genurl=tiger.ctr -F tiger.dat

    may create tiger.ctr with -

    lat=36.042108&lon=-86.877408&ht=0.161172&wid=0.591771&iwd=768&iht=768

    +

    +lat=36.042108&lon=-86.877408&ht=0.161172&wid=0.591771&iwd=768&iht=768

    After uploading tiger.dat to a public server, a request to

     http://tiger.census.gov/cgi-bin/mapgen?murl=$THATFILE$(cat tiger.ctr)

    will return a gif file from the tiger server that's suitably scaled. -

    margin option

    +

    margin option

    Margin for map. Degrees or percentage.

    This option specifies a margin around the maps for the genurl options. The margin may be specified in either decimal degrees or as a percentage.

    This option is most useful for ensuring there is adaequate space for the label around the markers when generating automatically scaled maps. -

    snlen option

    +

    snlen option

    Max shortname length when used with -s.

    The snlen option controls the maximum length of names generated by the '-s' option. It's particularly useful in Tiger maps to avoid the amount of clutter generated by potentially lengthy labels on the markers. -

    oldthresh option

    +

    oldthresh option

    Days after which points are considered old.

    This options allows you to control the threshold in days between whether a pin is considered "new" (and thus potentially governed by the 'newmarker' option) or "old" (and thus potentially governed by the 'oldmarker' option). -

    oldmarker option

    +

    oldmarker option

    Marker type for old points.

    This option specifies the pin to be used if a waypoint has a creation -time newer than 'oldthresh' days.

    The default is "redpin".

    newmarker option

    +time newer than 'oldthresh' days.

    The default is "redpin".

    newmarker option

    Marker type for new points.

    This option specifies the pin to be used if a waypoint has a creation -time older than 'oldthresh' days.

    The default is "greenpin".

    suppresswhite option

    +time older than 'oldthresh' days.

    The default is "greenpin".

    suppresswhite option

    Suppress whitespace in generated shortnames.

    When set, this options tells the '-s' smartname generator to not allow any spaces in the labels generated for markers. -

    unfoundmarker option

    +

    unfoundmarker option

    Marker type for unfound points. -

    xpixels option

    +

    xpixels option

    Width in pixels of map.

    The xpixels argument lets you specify the number of pixels to be generated by the Tiger server along the horizontal axis when using the -'genurl' option.

    ypixels option

    +'genurl' option.

    ypixels option

    Height in pixels of map.

    The ypixels argument lets you specify the number of pixels to be generated by the Tiger server along the vertical axis when using the -'genurl' option.

    iconismarker option

    +'genurl' option.

    iconismarker option

    The icon description is already the marker.

    This options signifies that the icon in the incoming format is to be used without change in the generated Tiger output file. Without this option, GPSBabel tries to color pins based on their creation time and certain -Geocaching traits when available.

    Universal csv with field structure in first line (unicsv)

    +Geocaching traits when available.

    Universal csv with field structure in first line (unicsv)

    This format can... -

    • +

      • read waypoints

      -

      Unicsv examines the first line of a file to determine the field order and field separator in that file. It is thus read-only format.

      @@ -2880,7 +2992,7 @@ Geocaching traits when available.

    The list of keywords include "lat", "lon", "desc", "name", - "notes", "alt", "utm z", "utm n", "utm e", and "url". + "notes", "alt", "utm z", "utm n", "utm e", "utm c" and "url". Fuller spellings (i.e. "longitude") may be used.

    A typical file may be: @@ -2889,12 +3001,11 @@ Geocaching traits when available.

    -

    Vcard Output (for iPod) (vcard)

    +

    Vcard Output (for iPod) (vcard)

    This format can... -

    • +

      • write waypoints -

      -

      The vCard output is intended to be in a format that +

    The vCard output is intended to be in a format that enables waypoints to be viewed with an Apple iPod. This is achieved by mapping waypoint fields into vCard fields that can be displayed as 'Contacts' on the iPod. With the iPod mounted as a hard disk (see your @@ -2902,68 +3013,63 @@ iPod manual for instructions), the resulting VCF file should be moved into the iPod 'Contacts' folder. As an alternative, Mac OS X users may prefer to drag the VCF file into their address book and synchronize with the iPod using iSync. -

    encrypt option

    +

    encrypt option

    Encrypt hints using ROT13.

    By default geocaching hints are unencrypted; use this option to encrypt them. -

    Vito Navigator II tracks (vitosmt)

    +

    Vito Navigator II tracks (vitosmt)

    This format can... -

    • +

      • read and write waypoints -

      • +

      • read and write tracks -

      • +

      • read and write routes -

      -

      Vito Navigator II is a Pocket PC GPS application. This +

    Vito Navigator II is a Pocket PC GPS application. This format reads a Vito Navigator II .SMT track file and can work in either waypoint or track mode. The speed, heading and Dilution of Position data is written in the notes field.

    Support for writing .SMT tracks is very experimental and -may crash VitoNavigator II on the Pocket PC.

    WiFiFoFum 2.0 for PocketPC XML (wfff)

    +may crash VitoNavigator II on the Pocket PC.

    WiFiFoFum 2.0 for PocketPC XML (wfff)

    This format can... -

    • +

      • read waypoints -

      -

      WFFF is the export format for Aspecto Software's WiFiFoFum 2.0 for Windows Mobile PCs.

      It is a simple XML format that is read-only to GPSBabel and stores information about a WiFi stumbling session.

      All WiFi-specific elements are written in the description field, similar to the netstumbler format.

      aicicon option

      +

    WFFF is the export format for Aspecto Software's WiFiFoFum 2.0 for Windows Mobile PCs.

    It is a simple XML format that is read-only to GPSBabel and stores information about a WiFi stumbling session.

    All WiFi-specific elements are written in the description field, similar to the netstumbler format.

    aicicon option

    Infrastructure closed icon name. -

    aioicon option

    +

    aioicon option

    Infrastructure open icon name. -

    ahcicon option

    +

    ahcicon option

    Ad-hoc closed icon name. -

    ahoicon option

    +

    ahoicon option

    Ad-hoc open icon name. -

    snmac option

    +

    snmac option

    Shortname is MAC address. -

    Wintec WBT-100/200 Binary file format (wbt-bin)

    +

    Wintec WBT-100/200 Binary file format (wbt-bin)

    This format can... -

    • +

      • read tracks -

      -

      File protocol for the Wintec WBT-200™ +

    File protocol for the Wintec WBT-200™ GPS data logger. This format reads the binary file format created by Wintec's Windows application.

    Wintec WBT-200 -

    Example 3.3. Command showing conversion of a Wintec binary file to GPX

    gpsbabel -i wbt-bin -f tracks.bin -o
    -gpx -F out.gpx

    Wintec WBT-100/200 GPS Download (wbt)

    +

    Example 3.3. Command showing conversion of a Wintec binary file to GPX

    gpsbabel -i wbt-bin -f tracks.bin -o +gpx -F out.gpx


    Wintec WBT-100/200 GPS Download (wbt)

    This format can... -

    • +

      • read tracks -

      -

      Serial download protocol for the Wintec WBT-200™ GPS data logger. Although untested it is expected that this will also support the WBT-100.

      +

    Serial download protocol for the Wintec WBT-200™ GPS data logger. Although untested it is expected that this will also support the WBT-100.

    Wintec WBT-200 -

    Example 3.4. Command showing WBT-200 download and erase over Bluetooth on Mac OS X

    gpsbabel -i wbt,erase -f /dev/cu.WBT200-SPPslave-1 -o gpx -F out.gpx

    erase option

    +

    Example 3.4. Command showing WBT-200 download and erase over Bluetooth on Mac OS X

    gpsbabel -i wbt,erase -f /dev/cu.WBT200-SPPslave-1 -o gpx -F out.gpx


    erase option

    Erase device data after download. -

    This option erases the track log from the device after download.

    Yahoo Geocode API data (yahoo)

    +

    This option erases the track log from the device after download.

    Yahoo Geocode API data (yahoo)

    This format can... -

    • +

      • read waypoints

      -

      This format reads output from the Yahoo geocoding API. This feature of GPSBabel makes it easy to get geocoded results from Yahoo into your favorite mapping program, GPS receiver, or other format. -

      addrsep option

      +

      addrsep option

      String to separate concatenated address fields (default=", ").

      This option specifies the string GPSBabel should use to separate the parts @@ -2972,7 +3078,7 @@ not support street addresses, the street address fields from the Yahoo file are concatenated into the waypoint "notes" field.

      The default value for this option is a comma followed by a space (", "). -



      [1] This unit uses GPX format, not Garmin protocol. Therefore one should communicate with it by reading and writing GPX files instead of using this format.



    [1] This model does not support transfer of waypoints, tracks, or routes, but may be used with the realtime tracking feature.

    [2] This unit uses GPX format, not Garmin protocol. Therefore one should communicate with it by reading and writing GPX files instead of using this format. Members of this class of products do not support realtime positioning protocol.

    Chapter 4. Data Filters

    GPSBabel supports data filtering. Data filters are invoked from the command line via the '-x' option. It should be noted that data filters are invoked in the internal pipeline at the point that corresponds to their position on the @@ -3026,30 +3132,30 @@ the file option. Note that this filter currently will not work properly if your polygon contains one or both poles or if it spans the line of 180 degrees east or west longitude. -

    Example 4.1. Using the polygon filter

    +

    Example 4.1. Using the polygon filter

    Suppose you have a polygon file that defines the border of your county, called mycounty.txt. This command line will give you only the points in your county: -

    gpsbabel -i geo -f 1.loc -x polygon,file=mycounty.txt -o mapsend -F 2.wpt

    Example 4.2. Using the polygon and arc filters to find points in or nearly in a -polygon

    +

    gpsbabel -i geo -f 1.loc -x polygon,file=mycounty.txt -o mapsend -F 2.wpt


    Example 4.2. Using the polygon and arc filters to find points in or nearly in a +polygon

    Because the polygon and arc filters use the same file format, you can use them together to find all points that are "in or nearly in" a polygon. This can be useful if your waypoints or the boundaries of your polygon are not quite perfect, so you want to provide a buffer zone around it in case there are points nearby that should be in the polygon but aren't quite. -

    +

    gpsbabel -i gpx -f points.gpx -x stack,push -x polygon,file=mycounty.txt -x stack,swap -x arc,file=mycounty.txt,distance=1k -x stack,pop,append -x duplicate,shortname -o gpx -F nearmycounty.gpx -

    +

    This command makes a copy of the points, finds the ones that are in your your county, swaps that result with the copy of the original set of points, finds the ones from that set that are within 1 km of the border of the county, puts the two lists together, and then filters out any points that appear twice (This step is necessary because points inside the county but near the county line will be kept by both the polygon and the arc filter.) -

    file option

    +


    file option

    File containing vertices of polygon.

    This option is required. @@ -3092,12 +3198,12 @@ something like this sample: An arc file may optionally contain gaps in the arc. You may specify such a gap by inserting a line containing "#break" either on a line by itself or after the coordinates of the starting point of the new arc segment. -

    Example 4.3. Using the arc filter

    +

    Example 4.3. Using the arc filter

    Assuming the arc above is in a file called lima_rd.txt, the following command line would include only points within one mile of the section of Lima Road covered by the arc. -

    gpsbabel -i geo -f 1.loc -x arc,file=lima_rd.txt,distance=1 -o mapsend -F 2.wpt

    file option

    +

    gpsbabel -i geo -f 1.loc -x arc,file=lima_rd.txt,distance=1 -o mapsend -F 2.wpt


    file option

    File containing vertices of arc.

    This option is required. @@ -3143,8 +3249,8 @@ specified point will be removed from the dataset.

    By default, all remaining points are sorted so that points closer to the center appear earlier in the output file. -

    Example 4.4. Using the radius filter to find points close to a given point

    This example command line would include only points within 1 1/2 miles - of N30.000 W 90.000

    gpsbabel -i geo -f 1.loc -x radius,distance=1.5M,lat=30.0,lon=-90.0 -o mapsend -F 2.wpt

    lat option

    +

    Example 4.4. Using the radius filter to find points close to a given point

    This example command line would include only points within 1 1/2 miles + of N30.000 W 90.000

    gpsbabel -i geo -f 1.loc -x radius,distance=1.5M,lat=30.0,lon=-90.0 -o mapsend -F 2.wpt


    lat option

    Latitude for center point (D.DDDDD).

    This option is required. @@ -3222,16 +3328,16 @@ points are missing, the filter fills them in by following a straight line (actually a great circle) between the adjacent points. You must specify either the distance or the time option. -

    Example 4.5. Using the interpolate filter

    +

    Example 4.5. Using the interpolate filter

    This command line reads track.gpx and inserts points wherever two adjacent trackpoints are more than 10 seconds apart: -

    gpsbabel -i gpx -f track.gpx -x interpolate,time=10 -o gpx -F newtrack.gpx

    +

    gpsbabel -i gpx -f track.gpx -x interpolate,time=10 -o gpx -F newtrack.gpx

    This command reads track.gpx and inserts points wherever two adjacent trackpoints are more than 15 kilometers apart: -

    gpsbabel -i gpx -f track.gpx -x interpolate,distance=15k -o gpx -F newtrack.gpx

    +

    gpsbabel -i gpx -f track.gpx -x interpolate,distance=15k -o gpx -F newtrack.gpx

    This command reads track.gpx and inserts points wherever two adjacent trackpoints are more than 2 miles apart: -

    gpsbabel -i gpx -f track.gpx -x interpolate,distance=2m -o gpx -F newtrack.gpx

    time option

    +

    gpsbabel -i gpx -f track.gpx -x interpolate,distance=2m -o gpx -F newtrack.gpx


    time option

    Time interval in seconds.

    This option specifies the maximum allowable time interval between points in the @@ -3268,9 +3374,9 @@ This filter performs various operations on track data. This option changes the time of all trackpoints. This might be useful if your track must be moved by one or more hours because of an incorrect time zone. -

    Example 4.6. Time-shifting a track with the track filter

    +

    Example 4.6. Time-shifting a track with the track filter

    The following command line will shift all tracks to be one hour later. -

    gpsbabel -t -i gpx -f in.gpx -x track,move=+1h -o gpx -F out.gpx

    pack option

    +

    gpsbabel -t -i gpx -f in.gpx -x track,move=+1h -o gpx -F out.gpx


    pack option

    Pack all tracks into one.

    This option causes all tracks to be appended to one another to form a single @@ -3288,14 +3394,10 @@ If no other option is given to the track filter, this option is assumed. track, use the pack option before before using this. To split a single tracks into separate tracks for each day and name them, use this: -

    -gpsbabel -t -i gpx -f in.gpx -x \
    -   track,split,title="ACTIVE LOG \
    -    # %Y%m%d" -o gpx -F out.gpx

    If the input has multiple tracks, pack them together before -splitting them back apart per day thusly:

         	    
    -gpsbabel -t   -i gpx -f in.gpx  \
    -     -x track,pack,split,title="ACTIVE LOG # %D"  	\
    -     -o gpx -F out.gpx

    Additionally you can add an interval to the split +

    gpsbabel -t -i gpx -f in.gpx -x track,split,title="ACTIVE LOG # %Y%m%d" -o gpx -F out.gpx

    If the input has multiple tracks, pack them together before +splitting them back apart per day thusly:

    gpsbabel -t -i gpx -f in.gpx + -x track,pack,split,title="ACTIVE LOG # %D" + -o gpx -F out.gpx

    Additionally you can add an interval to the split option. With this the track will be split if the time between two points is greater than this parameter. The interval must be numeric and can be int days, hours, minutes @@ -3303,12 +3405,12 @@ gpsbabel -t -i gpx -f in.gpx \ or "s". If no trailing character is present, the units are assumed to be in seconds.

    For example, to split a track based on an four hour - interval, use this:

                
    -gpsbabel -t \ 
    -     -i gpx -f in.gpx \ 
    -     -x track,pack,split=4h,title="LOG # %c" \ 
    +         interval, use this:

    +gpsbabel -t + -i gpx -f in.gpx + -x track,pack,split=4h,title="LOG # %c" -o gpx -F out.gpx -

    sdistance option

    +

    sdistance option

    Split by distance.

    The input track will be split into several tracks if the distance between successive track points @@ -3319,12 +3421,12 @@ gpsbabel -t \ effect as the split option without parameters. If there is more than one track, use the pack option before before using this.

    For example, to split the track if the distance between - points is greater than 100 meters, use this:

    -gpsbabel -t \
    -     -i gpx -f in.gpx \
    -     -x track,pack,sdistance=0.1k" \
    +         points is greater than 100 meters, use this:

    +gpsbabel -t + -i gpx -f in.gpx + -x track,pack,sdistance=0.1k" -o gpx -F out.gpx -

    The sdistance option can be combined with the split option. +

    The sdistance option can be combined with the split option. The track then will be split only if both time and distance interval exceeds the supplied values. This technique can be used to filter out gaps from @@ -3333,21 +3435,21 @@ gpsbabel -t \ a distance over that given. This example splits the track if the device is without signal for at least 5 minutes - and during this time moves more than 300 meters:

    -gpsbabel -t \
    -     -i gpx -f in.gpx \
    -     -x track,pack,sdistance=0.3k,split=5m \
    +        and during this time moves more than 300 meters:

    +gpsbabel -t + -i gpx -f in.gpx + -x track,pack,sdistance=0.3k,split=5m -o gpx -F out.gpx -

    merge option

    +

    merge option

    Merge multiple tracks for the same way.

    This option puts all track points from all tracks into a single track and sorts them by time stamp. Points with identical time stamps will be dropped. -

    Example 4.7. Merging tracks with the track filter

    +

    Example 4.7. Merging tracks with the track filter

    Suppose you want to merge tracks recorded with two different GPS devices at the same time. To do that, use this command line: -

    gpsbabel -t -i gpx -f john.gpx -i gpx -f doe.gpx -x track,merge,title="COMBINED LOG" -o gpx -F john_doe.gpx

    name option

    +

    gpsbabel -t -i gpx -f john.gpx -i gpx -f doe.gpx -x track,merge,title="COMBINED LOG" -o gpx -F john_doe.gpx


    name option

    Use only track(s) where title matches given name.

    With the name option you can filter out a track by title. @@ -3368,10 +3470,10 @@ The value of this option must be in the form of YYYYMMDDHHMMSS, but it is not necessary to specify the smaller time units if they are not needed. That is, if you only care about points logged between 10 AM and 6 PM on a given date, you need not specify the minutes or seconds. -

    Example 4.8. Extracting a period of time with the track filter

    +

    Example 4.8. Extracting a period of time with the track filter

    To get only the parts of a track that were mapped on 20 July 2005 between 10 AM and 6 PM, use this command line: -

    gpsbabel -t -i gpx -f in.gpx -x track,start=2005072010,stop=2005072018 -o gpx -F out.gpx 

    stop option

    +

    gpsbabel -t -i gpx -f in.gpx -x track,start=2005072010,stop=2005072018 -o gpx -F out.gpx


    stop option

    Use only track points before this timestamp.

    This option is used in conjunction with the start option to @@ -3457,12 +3559,12 @@ This option is not valid in combination with any other option. There are three main types of data that GPSBabel deals with: waypoints, tracks, and routes. The nuketypes filter allows removing all the data of any or all of those three types. -

    Example 4.9. Filtering data types with nuketypes

    +

    Example 4.9. Filtering data types with nuketypes

    If you have a GPX file that contains routes, tracks, and waypoints and you want a GPX file that contains only tracks, you may use this filter to remove the waypoints and the routes with this command: -

    gpsbabel -i gpx -f bigfile.gpx -x nuketypes,waypoints,routes -o gpx -F tracksonly.gpx

    waypoints option

    +

    gpsbabel -i gpx -f bigfile.gpx -x nuketypes,waypoints,routes -o gpx -F tracksonly.gpx


    waypoints option

    Remove all waypoints from data stream.

    This option causes the nuketypes filter to discard all waypoints that are not @@ -3483,12 +3585,12 @@ options that specify how duplicates will be recognized, shortname and location. Generally, at least one of these options is required.

    Example 4.10. Using the duplicate filter to suppress points with the same - name and location

    + name and location

    This command line removes points that have duplicate short names and duplicate locations. The result would be a gpx file that more than likely contains only unique points and point data. -

     gpsbabel -i gpx -f 1.gpx -f 2.gpx -x duplicate,location,shortname -o gpx -F merged_with_no_dupes.gpx

    shortname option

    +

    gpsbabel -i gpx -f 1.gpx -f 2.gpx -x duplicate,location,shortname -o gpx -F merged_with_no_dupes.gpx


    shortname option

    Suppress duplicate waypoints based on name.

    This option is the one most often used with the duplicate filter. This @@ -3513,11 +3615,11 @@ duplicated waypoint, not just the second and subsequent instances. If your input file contains waypoints A, B, B, and C, the output file will contain waypoints A, B, and C without the all option, or just A and C with the all option. -

    Example 4.11. Using the duplicate filter to implement an "ignore list."

    +

    Example 4.11. Using the duplicate filter to implement an "ignore list."

    This option may be used to implement an "ignore list." In the following example, the duplicate filter is used to remove a list of waypoints to be ignored from a larger collection of waypoints: -

    gpsbabel -i gpx -f waypoints.gpx -i csv -f to_ignore.csv -x duplicate,shortname,all -o gpx -F filtered.gpx

    correct option

    +

    gpsbabel -i gpx -f waypoints.gpx -i csv -f to_ignore.csv -x duplicate,shortname,all -o gpx -F filtered.gpx


    correct option

    Use coords from duplicate points.

    This option is used to change the locations of waypoints without losing any @@ -3528,19 +3630,19 @@ longitude in the original waypoint. As an example, this option may be used to adjust the locations of "puzzle" geocaches in a Groundspeak pocket query:

    Example 4.12. Using the duplicate filter to correct the locations of "puzzle" -geocaches

    gpsbabel -i gpx -f 43622.gpx -i csv -f corrections.csv -x duplicate,shortname,correct -o gpx -F 43622-corrected.gpx

    +geocaches

    gpsbabel -i gpx -f 43622.gpx -i csv -f corrections.csv -x duplicate,shortname,correct -o gpx -F 43622-corrected.gpx

    After this command is run, the waypoints in the output file will have all of the descriptive information from 43622.gpx, but waypoints that were also found in corrections.csv will have their coordinates replaced with the coordinates from that file. -

    Remove Points Within Distance (position)

    +


    Remove Points Within Distance (position)

    This filter removes points based on their proximity to each other. A point is removed if it is within the specified distance of a point that has come before. -

    Example 4.13. Using the position filter to suppress close points

    +

    Example 4.13. Using the position filter to suppress close points

    The following command removes multiple points that are within one foot of each other, leaving just one. -

    gpsbabel -i geo -f 1.loc -f 2.loc -x position,distance=1f -o mapsend -F 3.wpt

    distance option

    +

    gpsbabel -i geo -f 1.loc -f 2.loc -x position,distance=1f -o mapsend -F 3.wpt


    distance option

    Maximum positional distance.

    This option specifies the minimum allowable distance between two points. If @@ -3560,7 +3662,7 @@ This filter is used to "fix" unreliable GPS data by discarding points with HDOP and/or VDOP above a specified limit. HDOP and VDOP are measures of the best possible horizontal or vertical precision for a given configuration of GPS satellites. -

    Example 4.14. Using the discard filter

     gpsbabel -i gpx -f in.gpx -x discard,hdop=10,vdop=20,hdopandvdop -o gpx -F out.gpx

    Contributed by Tobias Minich.

    hdop option

    +

    Example 4.14. Using the discard filter

    gpsbabel -i gpx -f in.gpx -x discard,hdop=10,vdop=20,hdopandvdop -o gpx -F out.gpx


    Contributed by Tobias Minich.

    hdop option

    Suppress waypoints with higher hdop.

    This option specifies the maximum allowable Horizontal Dilution of @@ -3614,29 +3716,29 @@ can fit in your computer's memory. points that are inside both counties are duplicated (but the duplicates can be removed with the DUPLICATE filter; see above.) -

               
    -gpsbabel -i gpx -f in.gpx \
    -         -x stack,push,copy \
    -         -x polygon,file=county_a.txt \    
    -         -x stack,swap \
    -         -x polygon,file=county_b.txt \
    -         -x stack,pop,append \
    +

    +gpsbabel -i gpx -f in.gpx + -x stack,push,copy + -x polygon,file=county_a.txt + -x stack,swap + -x polygon,file=county_b.txt + -x stack,pop,append -o gpx -F out.gpx -

    This example reads a large list of waypoints and +

    This example reads a large list of waypoints and extracts the points within 20 miles of each of two cities, writing the waypoint descriptions into two different PalmDoc files and exporting all of the points to the GPS receiver: -

               
    -gpsbabel -i gpx -f indiana.gpx \
    -         -x stack,push,copy \
    -         -x radius,lat=41.0765,lon=-85.1365,distance=20m \
    -         -o palmdoc,dbname=Fort\ Wayne -F fortwayne.pdb \
    -         -x stack,swap \
    -         -x radius,lat=39.7733,lon=-86.1433,distance=20m \
    -         -o palmdoc,dbname=Indianapolis -F indianapolis.pdb \
    -         -x stack,pop,append \
    +

    +gpsbabel -i gpx -f indiana.gpx + -x stack,push,copy + -x radius,lat=41.0765,lon=-85.1365,distance=20m + -o palmdoc,dbname=Fort\ Wayne -F fortwayne.pdb + -x stack,swap + -x radius,lat=39.7733,lon=-86.1433,distance=20m + -o palmdoc,dbname=Indianapolis -F indianapolis.pdb + -x stack,pop,append -o magellan -F fwaind.wpt -

    push option

    +

    push option

    Push waypoint list onto stack.

    This is one of three "primary" options to the stack filter. @@ -3711,7 +3813,7 @@ in the original route and the length of the original route. For example, suppose you have a route from Street Atlas 2003 that you wish to use with a Magellan GPS receiver that only supports up to 50 points in a route: -

    gpsbabel -r -i saroute -f RoadTrip.anr -x simplify,count=50 -o magellan  -F grocery.rte

    count option

    +

    gpsbabel -r -i saroute -f RoadTrip.anr -x simplify,count=50 -o magellan -F grocery.rte

    count option

    Maximum number of points in route.

    This option specifies the maximum number of points which may appear in the @@ -3747,7 +3849,7 @@ this is the default.

    This option instructs GPSBabel to simplify by removing points that cause the smallest change in the overall length of the route first. -

    Transformate waypoints into a route, tracks into routes, ... (transform)

    +

    Transform waypoints into a route, tracks into routes, ... (transform)

    This filter can be used to convert GPS data between different data types.

    Some GPS data formats support only some subset of waypoints, tracks, @@ -3756,38 +3858,59 @@ smallest change in the overall length of the route first. as those from a CSV file) into a track or vice versa.

    The following example show you how to create a route from a waypoint table. -

    gpsbabel -i csv waypts.txt -x transform,rte=wpt -o gpx -F route.gpx

    +

    gpsbabel -i csv waypts.txt -x transform,rte=wpt -o gpx -F route.gpx

    Only the first letter of option value decides which transformation will be done. Depending on the used option it can be only 'W' for waypoints, 'R' for routes or 'T' for tracks.

    wpt option

    Transform track(s) or route(s) into waypoint(s) [R/T]. -

    rte option

    +

    +This option selects the destination type of this filter to be waypoints. +Choose this when you want to convert tracks or routes into waypoints. +

    Example 4.15. Converting a track to a sequence of waypoints

    +Say you you have a KML file that contains a track but you want to convert it to a CSV file that can contain only waypoints, perhaps to import into a spreadsheet. Use the following command: +

    gpsbabel -i kml -f blah.kml -x transform,wpt=trk -o csv -F blah.txt


    rte option

    Transform waypoint(s) or track(s) into route(s) [W/T]. -

    trk option

    +

    +This option selects the destination type of this filter to be routes. Choose this when you want to convert tracks into waypoints routes. A single route will be created in the sequence they appear in the input. +

    Example 4.16. Converting a pile of waypoints to a GPX route

    +Say you you have a data file that came from CSV file that you want to convert +to a GPX route that can be loaded into Mapsource. Use the following command: +

    gpsbabel -i csv -f blah.txt -x transform,rte=wpt -o gdb -F blah.gdb


    trk option

    Transform waypoint(s) or route(s) into tracks(s) [W/R]. -

    del option

    +

    +This option selects the destination type of this filter to be tracks. +Choose this when you want to create tracks from a list of waypoints or routes. +A single track will be created in the sequence they appear in the input. +

    Example 4.17. Converting a pile of waypoints to a GPX track

    +Say you you have a data file that came from CSV file that you want to convert +to a GPX track that can be loaded into Mapsource. Use the following command: +

    gpsbabel -i csv -f blah.txt -x transform,trk=wpt -o gdb -F blah.gdb


    del option

    Delete source data after transformation. -

    Appendix A. Supported Datums

    +

    +This option, when used in connction with the wpt, rte, or trk options, tells +GPSBabel to delete the source data after conversion. This is most useful if +you are trying to avoid duplicated data in the output. +

    Example 4.18. Convert a GPX track to GPX waypoints, tossing the original track

    gpsbabel -i gpx -f blah.gpx -x transform,wpt=trk,del -o gpx -F converted.gpx


    Appendix A. Supported Datums

    Some formats in GPSBabel support multiple datums. For example, the datum option to the garmin_txt format allows you to specify a datum for the output file.

    The following is a list of the datums supported by GPSBabel. -

    AdindanCarribean NAD27Hjorsey 1955NahrwanSanto (DOS)
    AFGCarthageHong Kong 1963Naparima BWISapper Hill 43
    Ain-El-AbdCent America NAD27Hu-Tzu-ShanNorth America 83Schwarzeck
    Alaska-NAD27Chatham 1971IndianN. America 1927 meanSicily
    Alaska-CanadaChua AstroIranObservatorio 1966Sierra Leone 1960
    Anna-1-AstroCorrego AlegreIreland 1965Old EgyptianS. Am. 1969 mean
    ARC 1950 MeanCuba NAD27ISTS 073 Astro 69Old Hawaiian_meanSouth Asia
    ARC 1960 MeanCyprusJohnston Island 61Old Hawaiian KauaiSoutheast Base
    Asc Island 58Djakarta(Batavia)KandawalaOld Hawaiian MauiSouthwest Base
    Astro B4DOS 1968Kerguelen IslandOld Hawaiian OahuTananarive Obs 25
    Astro Beacon EEaster lsland 1967Kertau 48OmanThai/Viet (Indian)
    Astro pos 71/4EgyptL.C. 5 AstroOSGB36Timbalai 1948
    Astro stn 52European 1950La ReunionPico De Las NievesTokyo mean
    Australia Geo 1984European 1950 meanLiberia 1964Pitcairn Astro 67Tristan Astro 1968
    Bahamas NAD27European 1979 meanLuzonS. Am. 1956 mean(P)United Arab Emirates
    Bellevue IGNFinnish NauticalMahe 1971S. Chilean 1963 (P)Viti Levu 1916
    Bermuda 1957Gandajika BaseMarco AstroPuerto RicoWake Eniwetok 60
    Bukit RimpahGeodetic Datum 49Masirah Is. NahrwanPulkovo 1942WGS 72
    Camp_Area_AstroGhanaMassawaQornoqWGS 84
    Campo_InchauspeGreenland NAD27MerchichQuatar NationalYacare
    Canada_Mean(NAD27)Guam 1963Mexico NAD27Rome 1940Zanderij
    Canal_Zone_(NAD27)Gunung SegaraMidway Astro 61S-42(Pulkovo1942)Sweden
    Canton_Island_1966Gunung Serindung 1962MindanaoS.E.Asia_(Indian) 
    CapeGUX1 AstroMinnaSAD-69/Brazil 
    Cape_Canaveral_meanHerat NorthMontjong LoweSanta Braz 

    Appendix B. Garmin Icons

    +

    AdindanCuba NAD27La ReunionQornoq
    AFGCyprusLiberia 1964Quatar National
    Ain-El-AbdDjakarta(Batavia)LuzonRome 1940
    Alaska-NAD27DOS 1968Mahe 1971S-42(Pulkovo1942)
    Alaska-CanadaEaster lsland 1967Marco AstroS.E.Asia_(Indian)
    Anna-1-AstroEgyptMasirah Is. NahrwanSAD-69/Brazil
    ARC 1950 MeanEuropean 1950MassawaSanta Braz
    ARC 1960 MeanEuropean 1950 meanMerchichSanto (DOS)
    Asc Island 58European 1979 meanMexico NAD27Sapper Hill 43
    Astro B4Finnish NauticalMidway Astro 61Schwarzeck
    Astro Beacon EGandajika BaseMindanaoSicily
    Astro pos 71/4Geodetic Datum 49MinnaSierra Leone 1960
    Astro stn 52GhanaMontjong LoweS. Am. 1969 mean
    Australia Geo 1984Greenland NAD27NahrwanSouth Asia
    Bahamas NAD27Guam 1963Naparima BWISoutheast Base
    Bellevue IGNGunung SegaraNorth America 83Southwest Base
    Bermuda 1957Gunung Serindung 1962N. America 1927 meanTananarive Obs 25
    Bukit RimpahGUX1 AstroObservatorio 1966Thai/Viet (Indian)
    Camp_Area_AstroHerat NorthOld EgyptianTimbalai 1948
    Campo_InchauspeHjorsey 1955Old Hawaiian_meanTokyo mean
    Canada_Mean(NAD27)Hong Kong 1963Old Hawaiian KauaiTristan Astro 1968
    Canal_Zone_(NAD27)Hu-Tzu-ShanOld Hawaiian MauiUnited Arab Emirates
    Canton_Island_1966IndianOld Hawaiian OahuViti Levu 1916
    CapeIranOmanWake Eniwetok 60
    Cape_Canaveral_meanIreland 1965OSGB36WGS 72
    Carribean NAD27ISTS 073 Astro 69Pico De Las NievesWGS 84
    CarthageJohnston Island 61Pitcairn Astro 67Yacare
    Cent America NAD27KandawalaS. Am. 1956 mean(P)Zanderij
    Chatham 1971Kerguelen IslandS. Chilean 1963 (P)Sweden
    Chua AstroKertau 48Puerto Rico 
    Corrego AlegreL.C. 5 AstroPulkovo 1942 

    Appendix B. Garmin Icons

    Following is a list of the valid values for the garmin deficon option. These values are also used internally by the GDB, -BCR, +BCR, Mapsource, Geoniche, GPilotS, PCX, and PSITrex formats. -

    AirportContact, Big EarsGhost TownNavaid, AmberReef
    Amusement ParkContact, BikerGlider AreaNavaid, BlackResidence
    Anchor ProhibitedContact, BugGolf CourseNavaid, BlueRestaurant
    Asian FoodContact, CatGreen circleNavaid, GreenRestricted Area
    Ball ParkContact, DogGreen DiamondNavaid, Green/RedRestroom
    BankContact, DreadlocksGreen Letter ANavaid, Green/WhiteRV Park
    BarContact, Female1Green Letter BNavaid, OrangeScales
    BeachContact, Female2Green Letter CNavaid, RedScenic Area
    BeaconContact, Female3Green Letter DNavaid, Red/GreenSchool
    BellContact, GoateeGreen Number 0Navaid, Red/WhiteSeafood
    Bike TrailContact, Kung-FuGreen Number 1Navaid, VioletSeaplane Base
    Blue CircleContact, PigGreen Number 2Navaid, WhiteShipwreck
    Blue DiamondContact, PirateGreen Number 3Navaid, White/GreenShopping Center
    Blue Letter AContact, RangerGreen Number 4Navaid, White/RedShort Tower
    Blue Letter BContact, SmileyGreen Number 5Non-directional beaconShower
    Blue Letter CContact, SpikeGreen Number 6NullSki Resort
    Blue Letter DContact, SumoGreen Number 7Oil FieldSkiing Area
    Blue Number 0Controlled AreaGreen Number 8Open 24 HoursSkull and Crossbones
    Blue Number 1Convenience StoreGreen Number 9Parachute AreaSmall City
    Blue Number 2CrossingGreen OvalParkSoft Field
    Blue Number 3DamGreen RectangleParking AreaStadium
    Blue Number 4Danger AreaGreen SquarePharmacyState Hwy
    Blue Number 5DeliGreen TrianglePicnic AreaSteak
    Blue Number 6Department StoreHeliportPin, BlueStreet Intersection
    Blue Number 7Diamond, BlueHornPin, GreenSummit
    Blue Number 8Diamond, GreenHotelPin, RedSwimming Area
    Blue Number 9Diamond, RedHousePizzaTACAN
    Blue OvalDiver Down Flag 1Hunting AreaPolice StationTall Tower
    Blue RectangleDiver Down Flag 2Ice SkatingPost OfficeTelephone
    Blue SquareDockInformationPost OfficeTide/Current PRediction Station
    Blue TriangleDrinking WaterIntersectionPrivate FieldToll Booth
    Boat RampDropoffIntl freeway hwyRadio BeaconTracBack Point
    Border Crossing (Port Of Entry)Elevation pointIntl national hwyRamp intersectionTrail Head
    Bottom ConditionsEvent CacheItalian foodRed circleTruck Stop
    BowlingExitLarge exit without servicesRed DiamondTunnel
    BridgeExit without servicesLarge Ramp intersectionRed Letter AU Marina
    BuildingFast FoodLeveeRed Letter BU stump
    CampgroundFirst approach fixLightRed Letter CUltralight Area
    CarFishing AreaLive TheaterRed Letter DUnknown Cache
    Car RentalFishing Hot Spot FacilityLocalizer Outer MarkerRed Number 0US hwy
    Car RepairFitness CenterLocationless (Reverse) CacheRed Number 1VHF Omni-range
    CemeteryFlagLodgingRed Number 2Virtual cache
    ChurchFlag, BlueMan OverboardRed Number 3VOR-DME
    Circle with XFlag, GreenMarinaRed Number 4VOR/TACAN
    City (Capitol)Flag, RedMedical FacilityRed Number 5Water Hydrant
    City (Large)ForestMicro-CacheRed Number 6Waypoint
    City (Medium)Gambling/casinoMile MarkerRed Number 7Webcam Cache
    City (Small)Gas StationMilitaryRed Number 8Weed Bed
    CivilGeocacheMineRed Number 9White Buoy
    Coast GuardGeocache FoundMissed approach pointRed OvalWhite Dot
    Contact, AfroGeographic place name, landMovie TheaterRed RectangleWrecker
    Contact, AlienGeographic place name, Man-madeMulti-CacheRed SquareZoo
    Contact, Ball CapGeographic place name, waterMuseumRed Triangle 

    Appendix C. GPSBabel XCSV Style Files

    Introduction

    +

    ATVContact, GlassesHunting AreaNumber 0, GreenScales
    AirportContact, GoateeIce SkatingNumber 0, RedScenic Area
    Amusement ParkContact, Kung-FuInformationNumber 1, BlueSchool
    AnchorContact, PandaIntersectionNumber 1, GreenSeafood
    Anchor ProhibitedContact, PigIntl freeway hwyNumber 1, RedSeaplane Base
    Animal TracksContact, PirateIntl national hwyNumber 2, BlueShipwreck
    Asian FoodContact, RangerItalian foodNumber 2, GreenShopping Center
    Bait and TackleContact, SmileyLarge Ramp intersectionNumber 2, RedShort Tower
    Ball ParkContact, SpikeLarge exit without servicesNumber 3, BlueShower
    BankContact, SumoLetter A, BlueNumber 3, GreenSki Resort
    BarControlled AreaLetter A, GreenNumber 3, RedSkiing Area
    BeachConvenience StoreLetter A, RedNumber 4, BlueSkull and Crossbones
    BeaconCoverLetter B, BlueNumber 4, GreenSmall City
    BellCoveyLetter B, GreenNumber 4, RedSmall Game
    Big GameCrossingLetter B, RedNumber 5, BlueSoft Field
    Bike TrailDamLetter C, BlueNumber 5, GreenSquare, Blue
    BlindDanger AreaLetter C, GreenNumber 5, RedSquare, Green
    Block, BlueDeliLetter C, RedNumber 6, BlueSquare, Red
    Block, GreenDepartment StoreLetter D, BlueNumber 6, GreenStadium
    Block, RedDiamond, BlueLetter D, GreenNumber 6, RedState Hwy
    Blood TrailDiamond, GreenLetter D, RedNumber 7, BlueSteak
    Boat RampDiamond, RedLetterbox CacheNumber 7, GreenStreet Intersection
    Border Crossing (Port Of Entry)Diver Down Flag 1LeveeNumber 7, RedStump
    Bottom ConditionsDiver Down Flag 2LibraryNumber 8, BlueSummit
    BowlingDockLightNumber 8, GreenSwimming Area
    BridgeDot, WhiteLive TheaterNumber 8, RedTACAN
    BuildingDrinking WaterLocalizer Outer MarkerNumber 9, BlueTall Tower
    Buoy, WhiteDropoffLocationless (Reverse) CacheNumber 9, GreenTelephone
    CampgroundElevation pointLodgeNumber 9, RedTide/Current PRediction Station
    CarEvent CacheLodgingOil FieldToll Booth
    Car RentalExitMan OverboardOpen 24 HoursTracBack Point
    Car RepairExit without servicesMarinaOval, BlueTrail Head
    CemeteryFast FoodMedical FacilityOval, GreenTree Stand
    ChurchFirst approach fixMicro-CacheOval, RedTreed Quarry
    Circle with XFishing AreaMile MarkerParachute AreaTriangle, Blue
    Circle, BlueFishing Hot Spot FacilityMilitaryParkTriangle, Green
    Circle, GreenFitness CenterMineParking AreaTriangle, Red
    Circle, RedFlagMissed approach pointPharmacyTruck
    City (Capitol)Flag, BlueMovie TheaterPicnic AreaTruck Stop
    City (Large)Flag, GreenMulti-CachePin, BlueTunnel
    City (Medium)Flag, RedMulti-CachePin, GreenU Marina
    City (Small)Food SourceMuseumPin, RedU stump
    City HallForestNavaid, AmberPizzaUS hwy
    CivilFurbearerNavaid, BlackPolice StationUltralight Area
    Coast GuardGambling/casinoNavaid, BluePost OfficeUnknown Cache
    Contact, AfroGas StationNavaid, GreenPost OfficeUpland Game
    Contact, AlienGeocacheNavaid, Green/RedPrivate FieldVHF Omni-range
    Contact, Ball CapGeocache FoundNavaid, Green/WhitePuzzle CacheVOR-DME
    Contact, Big EarsGeographic place name, Man-madeNavaid, OrangeRV ParkVOR/TACAN
    Contact, BikerGeographic place name, landNavaid, RedRadio BeaconVirtual cache
    Contact, BlondeGeographic place name, waterNavaid, Red/GreenRamp intersectionWater Hydrant
    Contact, BugGhost TownNavaid, Red/WhiteRectangle, BlueWater Source
    Contact, CatGlider AreaNavaid, VioletRectangle, GreenWaterfowl
    Contact, ClownGolf CourseNavaid, WhiteRectangle, RedWaypoint
    Contact, DogGround TransportationNavaid, White/GreenReefWebcam Cache
    Contact, DreadlocksHeliportNavaid, White/RedResidenceWeed Bed
    Contact, Female1HornNon-directional beaconRestaurantWinery
    Contact, Female2HotelNullRestricted AreaWrecker
    Contact, Female3HouseNumber 0, BlueRestroomZoo

    Appendix C. GPSBabel XCSV Style Files

    Introduction

    Often it is desirable to add a new file format for "one-off" work (perhaps you want to export something to a spreadsheet or graphing program) or to read a format that GPSBabel does not yet support. For suitably simple formats, @@ -3804,7 +3927,7 @@ or want, you must tell GPSBabel to use the xcsv format and have the xcsv format use that file. If you created a new style file called "mystyle.style" and you want to write the waypoints from a GPX file named "mine.gpx" to it, you would issue a command like: -

    gpsbabel -i gpx -f mine.gpx -o xcsv,style=mystyle.style -f mine.new

    +

    gpsbabel -i gpx -f mine.gpx -o xcsv,style=mystyle.style -f mine.new

    You might then examine mine.new to see if it met your expectations. If not, you could continue to tweak mystyle.style until it did, rerunning the above @@ -3843,8 +3966,9 @@ PROLOGUE Name Latitude Longitude Description URL Type Container Diff Terr

    #
    # INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:
    -# NOTE: MS S&T ONLY IMPORTS DATA, IT DOESN'T EXPORT THIS ANYWHERE SO WE CAN
    -#       HAVE OUR WAY WITH THE FORMATTING. 
    +# NOTE: MS S&T ONLY IMPORTS DATA, IT DOESN'T 
    +#       EXPORT THIS ANYWHERE SO WE CAN HAVE OUR 
    +#       WAY WITH THE FORMATTING. 
    #
    IFIELD SHORTNAME, "", "%s" # Name
    IFIELD LAT_DECIMAL, "", "%f" # Latitude
    @@ -3890,7 +4014,17 @@ this file.

    ENCODING

    Describes the character set used by this format. The value given must be one listed by 'gpsbabel -l'. example: -

       ENCODING             UTF-8	# Use UTF-8 for input and output.
    +

       ENCODING          UTF-8	# Use UTF-8 for input and output.
    +

    DATUM

    +This value specifies the GPS datum to be used on read or write. Valid values for this +option are listed in Appendix A, Supported Datums. +

       DATUM             European 1950
    +

    DATATYPE

    +Specifies the kind of data we have to read or write. +

    +By default all data are seen as waypoint data. With DATATYPE you are now able to bind +a specific type to this format. Possible values are WAYPOINT, ROUTE or TRACK. +

       DATATYPE          ROUTE # route-only format
     

    GPSBabel Behavior Directives

    There are a few available directives to control some of the internal processing functions of GPSbabel. @@ -4025,14 +4159,14 @@ examples: is CHARACTER data and requires a character array printf conversion.

    example: -

       IFIELD SHORTNAME,"","%s"   # (write shortname in the output file)
    +

       IFIELD SHORTNAME,"","%s"
     

    DESCRIPTION

    A DESCRIPTION is generally a long description of the waypoint. A DESCRIPTION maps to the GPSBabel variable ->description and is otherwise handled exactly like a SHORTNAME.

    examples: -

       IFIELD DESCRIPTION,"","%s" # (write description in the output file)
    +

       IFIELD DESCRIPTION,"","%s" 
     

    NOTES

    NOTES are generally everything else about a waypoints. NOTES map to the GPSBabel variable ->notes and is otherwise handled exactly like a @@ -4042,21 +4176,21 @@ examples: ->url and is otherwise handled exactly like a SHORTNAME.

    example: -

       IFIELD URL,"","%s" #	(writes the URL in the output file)
    +

       IFIELD URL,"","%s"
     

    URL_LINK_TEXT

    URL_LINK_TEXT is a textual description of where a URL points. URL_LINK_TEXT maps to the GPSBabel variable ->url_link_text and is otherwise handled exactly like a SHORTNAME.

    example: -

       IFIELD URL_LINK_TEXT,"","%s" # (writes link text in the output file)
    +

       IFIELD URL_LINK_TEXT,"","%s" 
     

    ICON_DESCR

    ICON_DESCR is a textual description of an icon type for a waypoint. ICON_DESCR maps to the GPSBabel variable ->icon_desc and is otherwise handled exactly like a SHORTNAME.

    example: -

       IFIELD ICON_DESCR,"","%s" # (writes link text in the output file)
    +

       IFIELD ICON_DESCR,"","%s" 
     

    LAT_DECIMAL

    LAT_DECIMAL defines LATITUDE in DECIMAL format. Note that this is a PURE signed decimal format (i.e. -91.0000). This data is handled internally as @@ -4102,12 +4236,15 @@ examples: latitude and longitude based on what is in the file.

    examples: -

       IFIELD LAT_HUMAN_READABLE,"","%c %d %f"   # (writes N 31 40.000)
    +

    +   #  (writes N 31 40.000)
    +   IFIELD LAT_HUMAN_READABLE,"","%c %d %f"   
    +   #  (writes "31 deg 40.000 min N")
        IFIELD LAT_HUMAN_READABLE,"","%d deg %f min %c"
    -                              #  (writes "31 deg 40.000 min N")
    -          #  Note that this string will confuse the reading routine due 
    -          #  to the letter "n" in "min" and the letter "e" in "deg."
    -   IFIELD LAT_HUMAN_READABLE,"","%d %d %f%c" # (writes 31 40 00.000N)
    +   #  Note that this string will confuse the reading routine due 
    +   #  to the letter "n" in "min" and the letter "e" in "deg."
    +   # (writes 31 40 00.000N)
    +   IFIELD LAT_HUMAN_READABLE,"","%d %d %f%c" 
     

    LON_HUMAN_READABLE

    See LAT_HUMAN_READABLE except LON_HUMAN_READABLE defines LONGITUDE.

    LATLON_HUMAN_READABLE

    diff --git a/gpx.c b/gpx.c index 0541478f9..b204f5f5a 100644 --- a/gpx.c +++ b/gpx.c @@ -1,7 +1,7 @@ /* Access GPX data files. - Copyright (C) 2002, 2003, 2004, 2005 Robert Lipe, robertlipe@usa.net + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -45,8 +45,8 @@ static vmem_t current_tag; static waypoint *wpt_tmp; static int cache_descr_is_html; -static FILE *fd; -static FILE *ofd; +static gbfile *fd; +static gbfile *ofd; static short_handle mkshort_handle; static const char *input_string = NULL; @@ -227,18 +227,18 @@ gpx_write_gdata(gpx_global_entry *ge, char *tag) return; } - fprintf(ofd, "<%s>", tag); + gbfprintf(ofd, "<%s>", tag); QUEUE_FOR_EACH(&ge->queue, elem, tmp) { gep = BASE_STRUCT(elem, gpx_global_entry, queue); - fprintf(ofd, "%s", gep->tagdata); + gbfprintf(ofd, "%s", gep->tagdata); /* Some tags we just output once. */ if ((0 == strcmp(tag, "url")) || (0 == strcmp(tag, "email"))) { break; } - fprintf(ofd, " "); + gbfprintf(ofd, " "); } - fprintf(ofd, "\n", tag); + gbfprintf(ofd, "\n", tag); } @@ -277,20 +277,28 @@ tag_mapping tag_path_map[] = { { tt_wpt_link_text, 0, "/gpx/wpt/link/text", 0UL }, /* GPX 1.1 */ { tt_wpt_sym, 0, "/gpx/wpt/sym", 0UL }, { tt_wpt_type, 1, "/gpx/wpt/type", 0UL }, - - { tt_cache, 1, "/gpx/wpt/groundspeak:cache", 0UL }, - { tt_cache_name, 1, "/gpx/wpt/groundspeak:cache/groundspeak:name", 0UL }, - { tt_cache_container, 1, "/gpx/wpt/groundspeak:cache/groundspeak:container", 0UL }, - { tt_cache_type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:type", 0UL }, - { tt_cache_difficulty, 1, "/gpx/wpt/groundspeak:cache/groundspeak:difficulty", 0UL }, - { tt_cache_terrain, 1, "/gpx/wpt/groundspeak:cache/groundspeak:terrain", 0UL }, - { tt_cache_hint, 1, "/gpx/wpt/groundspeak:cache/groundspeak:encoded_hints", 0UL }, - { tt_cache_desc_short, 1, "/gpx/wpt/groundspeak:cache/groundspeak:short_description", 0UL }, - { tt_cache_desc_long, 1, "/gpx/wpt/groundspeak:cache/groundspeak:long_description", 0UL }, - { tt_cache_log_wpt, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:log_wpt", 0UL }, - { tt_cache_log_type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:type", 0UL }, - { tt_cache_log_date, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:date", 0UL }, - { tt_cache_placer, 1, "/gpx/wpt/groundspeak:cache/groundspeak:owner", 0UL }, + + /* Double up the GPX 1.0 and GPX 1.1 styles */ +#define GEOTAG(type,name) \ + {type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:" name, 0UL }, \ + {type, 1, "/gpx/wpt/extensions/cache/" name, 0UL } + + GEOTAG( tt_cache, "cache"), + GEOTAG( tt_cache_name, "name"), + GEOTAG( tt_cache_container, "container"), + GEOTAG( tt_cache_type, "type"), + GEOTAG( tt_cache_difficulty, "difficulty"), + GEOTAG( tt_cache_terrain, "terrain"), + GEOTAG( tt_cache_hint, "encoded_hints"), + GEOTAG( tt_cache_desc_short, "short_description"), + GEOTAG( tt_cache_desc_long, "long_description"), + GEOTAG( tt_cache_placer, "owner"), + { tt_cache_log_wpt, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:log_wpt"}, + { tt_cache_log_wpt, 1, "/gpx/wpt/extensions/cache/logs/log/log_wpt"}, + { tt_cache_log_type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:type"}, + { tt_cache_log_type, 1, "/gpx/wpt/extensions/cache/logs/log/type"}, + { tt_cache_log_date, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:date"}, + { tt_cache_log_date, 1, "/gpx/wpt/extensions/cache/logs/log/date"}, { tt_garmin_extension, 0, "/gpx/wpt/extensions", 0UL }, { tt_garmin_waypt_extension, 0, "/gpx/wpt/extensions/gpxx:WaypointExtension", 0UL }, @@ -726,7 +734,7 @@ gs_get_container(geocache_container t) } time_t -xml_parse_time( const char *cdatastr ) +xml_parse_time( const char *cdatastr, int *microsecs ) { int off_hr = 0; int off_min = 0; @@ -766,6 +774,12 @@ xml_parse_time( const char *cdatastr ) pointstr = strchr( timestr, '.' ); if ( pointstr ) { + if (microsecs) { + double fsec; + sscanf(pointstr, "%le", &fsec); + /* Round to avoid FP jitter */ + *microsecs = .5 + (fsec * 1000000.0) ; + } *pointstr = '\0'; } @@ -890,7 +904,7 @@ gpx_end(void *data, const XML_Char *xml_el) wpt_tmp->gc_data.placer = xstrdup(cdatastrp); break; case tt_cache_log_date: - gc_log_date = xml_parse_time( cdatastrp ); + gc_log_date = xml_parse_time( cdatastrp, NULL ); break; /* * "Found it" logs follow the date according to the schema, @@ -981,7 +995,7 @@ gpx_end(void *data, const XML_Char *xml_el) case tt_wpt_time: case tt_trk_trkseg_trkpt_time: case tt_rte_rtept_time: - wpt_tmp->creation_time = xml_parse_time( cdatastrp ); + wpt_tmp->creation_time = xml_parse_time( cdatastrp, &wpt_tmp->microseconds ); break; case tt_wpt_cmt: case tt_rte_rtept_cmt: @@ -1097,7 +1111,7 @@ static void gpx_rd_init(const char *fname) { if ( fname[0] ) { - fd = xfopen(fname, "r", MYNAME); + fd = gbfopen(fname, "r", MYNAME); } else { fd = NULL; @@ -1173,7 +1187,7 @@ gpx_rd_deinit(void) gpx_author = NULL; } if (fd) { - fclose(fd); + gbfclose(fd); } XML_ParserFree(psr); psr = NULL; @@ -1187,13 +1201,13 @@ gpx_wr_init(const char *fname) { mkshort_handle = mkshort_new_handle(); - ofd = xfopen(fname, "w", MYNAME); + ofd = gbfopen(fname, "w", MYNAME); } static void gpx_wr_deinit(void) { - fclose(ofd); + gbfclose(ofd); mkshort_del_handle(&mkshort_handle); } @@ -1225,16 +1239,19 @@ gpx_read(void) char *badchar; char *semi; int maxentlength = 8; - len = fread(buf, 1, MY_CBUF_SZ - maxentlength, fd); - done = feof(fd) || !len; + len = gbfread(buf, 1, MY_CBUF_SZ - maxentlength, fd); + done = gbfeof(fd) || !len; buf[len] = '\0'; + if (len < maxentlength) { + maxentlength = len; + } badchar = buf+len-maxentlength; badchar = strchr( badchar, '&' ); extra = maxentlength - 1; /* for terminator */ while ( badchar && len < MY_CBUF_SZ-1) { semi = strchr( badchar, ';'); while ( extra && !semi ) { - len += fread( buf+len, 1, 1, fd); + len += gbfread( buf+len, 1, 1, fd); buf[len]='\0'; extra--; if ( buf[len-1] == ';') @@ -1292,15 +1309,15 @@ static void fprint_tag_and_attrs( char *prefix, char *suffix, xml_tag *tag ) { char **pa; - fprintf( ofd, "%s%s", prefix, tag->tagname ); + gbfprintf( ofd, "%s%s", prefix, tag->tagname ); pa = tag->attributes; if ( pa ) { while ( *pa ) { - fprintf( ofd, " %s=\"%s\"", pa[0], pa[1] ); + gbfprintf( ofd, " %s=\"%s\"", pa[0], pa[1] ); pa += 2; } } - fprintf( ofd, "%s", suffix ); + gbfprintf( ofd, "%s", suffix ); } static void @@ -1316,7 +1333,7 @@ fprint_xml_chain( xml_tag *tag, const waypoint *wpt ) if ( tag->cdata ) { tmp_ent = xml_entitize( tag->cdata ); - fprintf( ofd, "%s", tmp_ent ); + gbfprintf( ofd, "%s", tmp_ent ); xfree(tmp_ent); } if ( tag->child ) { @@ -1324,14 +1341,14 @@ fprint_xml_chain( xml_tag *tag, const waypoint *wpt ) } if ( wpt && wpt->gc_data.exported && strcmp(tag->tagname, "groundspeak:cache" ) == 0 ) { - xml_write_time( ofd, wpt->gc_data.exported, + xml_write_time( ofd, wpt->gc_data.exported, 0, "groundspeak:exported" ); } - fprintf( ofd, "\n", tag->tagname); + gbfprintf( ofd, "\n", tag->tagname); } if ( tag->parentcdata ) { tmp_ent = xml_entitize(tag->parentcdata); - fprintf(ofd, "%s", tmp_ent ); + gbfprintf(ofd, "%s", tmp_ent ); xfree(tmp_ent); } tag = tag->sibling; @@ -1383,13 +1400,13 @@ write_gpx_url(const waypoint *waypointp) tmp_ent = xml_entitize(waypointp->url); if (gpx_wversion_num > 10) { - fprintf(ofd, " \n", + gbfprintf(ofd, " \n", urlbase ? urlbase : "", tmp_ent); write_optional_xml_entity(ofd, " ", "text", waypointp->url_link_text); - fprintf(ofd, " \n"); + gbfprintf(ofd, " \n"); } else { - fprintf(ofd, " %s%s\n", + gbfprintf(ofd, " %s%s\n", urlbase ? urlbase : "", tmp_ent); write_optional_xml_entity(ofd, " ", "urlname", waypointp->url_link_text); @@ -1430,19 +1447,19 @@ gpx_write_common_acc(const waypoint *waypointp, const char *indent) break; } if (fix) { - fprintf(ofd, "%s%s\n", indent, fix); + gbfprintf(ofd, "%s%s\n", indent, fix); } if (waypointp->sat > 0) { - fprintf(ofd, "%s%d\n", indent, waypointp->sat); + gbfprintf(ofd, "%s%d\n", indent, waypointp->sat); } if (waypointp->hdop) { - fprintf(ofd, "%s%f\n", indent, waypointp->hdop); + gbfprintf(ofd, "%s%f\n", indent, waypointp->hdop); } if (waypointp->vdop) { - fprintf(ofd, "%s%f\n", indent, waypointp->vdop); + gbfprintf(ofd, "%s%f\n", indent, waypointp->vdop); } if (waypointp->pdop) { - fprintf(ofd, "%s%f\n", indent, waypointp->pdop); + gbfprintf(ofd, "%s%f\n", indent, waypointp->pdop); } } @@ -1450,11 +1467,11 @@ static void gpx_write_common_position(const waypoint *waypointp, const char *indent) { if (waypointp->altitude != unknown_alt) { - fprintf(ofd, "%s%f\n", + gbfprintf(ofd, "%s%f\n", indent, waypointp->altitude); } if (waypointp->creation_time) { - xml_write_time(ofd, waypointp->creation_time, "time"); + xml_write_time(ofd, waypointp->creation_time, waypointp->microseconds, "time"); } } @@ -1494,7 +1511,7 @@ gpx_waypt_pr(const waypoint *waypointp) mkshort(mkshort_handle, odesc) : waypointp->shortname; - fprintf(ofd, "\n", + gbfprintf(ofd, "\n", waypointp->latitude, waypointp->longitude); @@ -1509,7 +1526,7 @@ gpx_waypt_pr(const waypoint *waypointp) if (gpx_wversion_num > 10) { garmin_fs_xml_fprint(ofd, waypointp); } - fprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); } static void @@ -1517,13 +1534,13 @@ gpx_track_hdr(const route_head *rte) { fs_xml *fs_gpx; - fprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); write_optional_xml_entity(ofd, " ", "name", rte->rte_name); write_optional_xml_entity(ofd, " ", "desc", rte->rte_desc); if (rte->rte_num) { - fprintf(ofd, "%d\n", rte->rte_num); + gbfprintf(ofd, "%d\n", rte->rte_num); } - fprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); fs_gpx = (fs_xml *)fs_chain_find( rte->fs, FS_GPX ); if ( fs_gpx ) { @@ -1536,7 +1553,7 @@ gpx_track_disp(const waypoint *waypointp) { fs_xml *fs_gpx; - fprintf(ofd, "\n", + gbfprintf(ofd, "\n", waypointp->latitude, waypointp->longitude); @@ -1545,11 +1562,11 @@ gpx_track_disp(const waypoint *waypointp) /* These were accidentally removed from 1.1 */ if (gpx_wversion_num == 10) { if (waypointp->course >= 0) { - fprintf(ofd, " %f\n", + gbfprintf(ofd, " %f\n", waypointp->course); } if (waypointp->speed >= 0) { - fprintf(ofd, " %f\n", + gbfprintf(ofd, " %f\n", waypointp->speed); } } @@ -1567,14 +1584,14 @@ gpx_track_disp(const waypoint *waypointp) fprint_xml_chain( fs_gpx->tag, waypointp ); } - fprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); } static void gpx_track_tlr(const route_head *rte) { - fprintf(ofd, "\n"); - fprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); } static @@ -1588,11 +1605,11 @@ gpx_route_hdr(const route_head *rte) { fs_xml *fs_gpx; - fprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); write_optional_xml_entity(ofd, " ", "name", rte->rte_name); write_optional_xml_entity(ofd, " ", "desc", rte->rte_desc); if (rte->rte_num) { - fprintf(ofd, " %d\n", rte->rte_num); + gbfprintf(ofd, " %d\n", rte->rte_num); } fs_gpx = (fs_xml *)fs_chain_find( rte->fs, FS_GPX ); @@ -1606,7 +1623,7 @@ gpx_route_disp(const waypoint *waypointp) { fs_xml *fs_gpx; - fprintf(ofd, " \n", + gbfprintf(ofd, " \n", waypointp->latitude, waypointp->longitude); @@ -1619,13 +1636,13 @@ gpx_route_disp(const waypoint *waypointp) fprint_xml_chain( fs_gpx->tag, waypointp ); } - fprintf(ofd, " \n"); + gbfprintf(ofd, " \n"); } static void gpx_route_tlr(const route_head *rte) { - fprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); } static @@ -1651,8 +1668,8 @@ gpx_write_bounds(void) track_disp_all(NULL, NULL, gpx_waypt_bound_calc); if (waypt_bounds_valid(&all_bounds)) { - fprintf(ofd, "\n", + gbfprintf(ofd, "\n", all_bounds.min_lat, all_bounds.min_lon, all_bounds.max_lat, all_bounds.max_lon); } @@ -1680,22 +1697,22 @@ gpx_write(void) setshort_length(mkshort_handle, short_length); - fprintf(ofd, "\n", global_opts.charset_name); - fprintf(ofd, "\n", global_opts.charset_name); + gbfprintf(ofd, "\n", xsi_schema_loc); + gbfprintf(ofd, "xsi:schemaLocation=\"%s\">\n", xsi_schema_loc); } else { - fprintf(ofd, + gbfprintf(ofd, "xsi:schemaLocation=" DEFAULT_XSI_SCHEMA_LOC_FMT">\n", gpx_wversion[0], gpx_wversion[2], gpx_wversion[0], gpx_wversion[2]); } if (gpx_wversion_num > 10) { - fprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); } gpx_write_gdata(&gpx_global->name, "name"); gpx_write_gdata(&gpx_global->desc, "desc"); @@ -1708,20 +1725,20 @@ gpx_write(void) gpx_write_gdata(&gpx_global->email, "email"); gpx_write_gdata(&gpx_global->url, "url"); gpx_write_gdata(&gpx_global->urlname, "urlname"); - xml_write_time( ofd, now, "time" ); + xml_write_time( ofd, now, 0, "time" ); gpx_write_gdata(&gpx_global->keywords, "keywords"); gpx_write_bounds(); if (gpx_wversion_num > 10) { - fprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); } waypt_disp_all(gpx_waypt_pr); gpx_route_pr(); gpx_track_pr(); - fprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); } diff --git a/gpxval b/gpxval index 98e694770..ffa5d87b4 100644 --- a/gpxval +++ b/gpxval @@ -1,15 +1,20 @@ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/robertl/xerces-c1_7_0-linux7.2/lib export PATH=$PATH:/home/robertl/xerces-c1_7_0-linux7.2/bin +validate() +{ + SAX2Count -p -f -v=always $* +} + gpxval() { echo "Validating $*" ./gpsbabel $* -o gpx -F /tmp/$$.gpx - SAX2Count /tmp/$$.gpx + validate /tmp/$$.gpx ./gpsbabel $* -o gpx,gpxver=1.0 -F /tmp/$$.gpx - SAX2Count /tmp/$$.gpx + validate /tmp/$$.gpx ./gpsbabel $* -o gpx,gpxver=1.1 -F /tmp/$$.gpx - SAX2Count /tmp/$$.gpx + validate /tmp/$$.gpx } diff --git a/gtm.c b/gtm.c index 379eb29a9..a1f7a2a5e 100644 --- a/gtm.c +++ b/gtm.c @@ -21,7 +21,7 @@ #include "defs.h" #include "jeeps/gpsmath.h" -static FILE *fd, *ofd; +static gbfile *file_in, *file_out; static int indatum; static int wp_count; static int ws_count; @@ -49,78 +49,35 @@ static int start_new; /* Read functions, according to specification. */ -static void -fread_discard(FILE *fd, int len) -{ - char buf[1024]; - fread(buf, 1, len, fd); -} - -static unsigned char -fread_byte(FILE *fd) -{ - unsigned char buf[1]; - fread(buf, 1, 1, fd); - return buf[0]; -} +#define fread_discard(a,b) gbfseek(a, (b), SEEK_CUR) +#define fread_byte(a) (unsigned char) gbfgetc(a) #if 0 /* not used */ static short int -fread_bool(FILE *fd) +fread_bool(gbfile *fd) { char buf[2]; - fread(buf, 2, 1, fd); + gbfread(buf, 2, 1, fd); return le_read16(buf) ? 1 : 0; } #endif -static short int -fread_integer(FILE *fd) -{ - char buf[2]; - fread(buf, 2, 1, fd); - return le_read16(buf); -} - -static int -fread_long(FILE *fd) -{ - char buf[4]; - fread(buf, 4, 1, fd); - return le_read32(buf); -} - -static float -fread_single(FILE *fd) -{ - unsigned char buf[4]; - float f; - int i; - fread(buf, 4, 1, fd); - i = le_read32(buf); - memcpy(&f, &i, 4); - return f; -} - -static double -fread_double(FILE *fd) -{ - char buf[8]; - fread(buf, 8, 1, fd); - return le_read_double(buf); -} +#define fread_integer(a) gbfgetint16(a) +#define fread_long(a) gbfgetint32(a) +#define fread_single(a) gbfgetflt(a) +#define fread_double(a) gbfgetdbl(a) static char * -fread_string(FILE *fd) +fread_string(gbfile *fd) { - int len = fread_integer(fd); char *val; + int len = fread_integer(fd); if (len == 0) return NULL; val = xmalloc(len+1); - fread(val, 1, len, fd); + gbfread(val, 1, len, fd); while (len != 0 && val[len-1] == ' ') len--; val[len] = 0; @@ -128,19 +85,21 @@ fread_string(FILE *fd) } static void -fread_string_discard(FILE *fd) +fread_string_discard(gbfile *fd) { char *temp = fread_string(fd); + if (temp != NULL) { xfree(temp); } } static char * -fread_fixedstring(FILE *fd, int len) +fread_fixedstring(gbfile *fd, int len) { char *val = xmalloc(len+1); - fread(val, 1, len, fd); + + gbfread(val, 1, len, fd); while (len != 0 && val[len-1] == ' ') len--; val[len] = 0; @@ -150,68 +109,28 @@ fread_fixedstring(FILE *fd, int len) /* Write functions, according to specification. */ static void -fwrite_null(FILE *fd, int len) +fwrite_null(gbfile *fd, int len) { char buf[1024]; - memset(buf, 0, len); - fwrite(buf, 1, len, fd); -} -static void -fwrite_byte(FILE *fd, unsigned char val) -{ - fwrite(&val, 1, 1, fd); -} - -static void -fwrite_bool(FILE *fd, short int val) -{ - char buf[2]; - buf[0] = buf[1] = val ? 0xff : 0x00; - fwrite(buf, 2, 1, fd); -} - -static void -fwrite_integer(FILE *fd, short int val) -{ - char buf[2]; - le_write16(buf, val); - fwrite(buf, 2, 1, fd); -} - -static void -fwrite_long(FILE *fd, int val) -{ - char buf[4]; - le_write32(buf, val); - fwrite(buf, 4, 1, fd); -} - -static void -fwrite_single(FILE *fd, float val) -{ - char buf[4]; - int i; - memcpy(&i, &val, 4); - le_write32(buf, i); - fwrite(buf, 4, 1, fd); + memset(buf, 0, len); + gbfwrite(buf, 1, len, fd); } -static void -fwrite_double(FILE *fd, double val) -{ - char buf[8]; - le_write_double(buf,val); - fwrite(buf, 8, 1, fd); -} +#define fwrite_byte(a,b) gbfputc((signed char)(b), a) +#define fwrite_bool(a,b) gbfputuint16((b) ? 0xffff : 0, a) +#define fwrite_integer(a,b) gbfputint16((b), a) +#define fwrite_long(a,b) gbfputint32((b), a) +#define fwrite_single(a,b) gbfputflt((b), a) +#define fwrite_double(a,b) gbfputdbl((b), a) static void -fwrite_string(FILE *fd, const char *str) +fwrite_string(gbfile *fd, const char *str) { if (str && str[0]) { int len = strlen(str); fwrite_integer(fd, len); - fwrite(str, 1, len, fd); + gbfwrite(str, 1, len, fd); } else { fwrite_integer(fd, 0); @@ -219,15 +138,16 @@ fwrite_string(FILE *fd, const char *str) } void -fwrite_fixedstring(FILE *fd, const char *str, int fieldlen) +fwrite_fixedstring(gbfile *fd, const char *str, int fieldlen) { int len = str ? strlen(str) : 0; + if (len > fieldlen) len = fieldlen; if (str) - fwrite(str, 1, len, fd); + gbfwrite(str, 1, len, fd); for (; len != fieldlen; len++) - fputc(' ', fd); + gbfputc(' ', fd); } /* Auxiliar functions */ @@ -442,9 +362,9 @@ gtm_rd_init(const char *fname) { int version; char *name; - fd = xfopen(fname, "rb", MYNAME); - version = fread_integer(fd); - name = fread_fixedstring(fd, 10); + file_in = gbfopen_le(fname, "rb", MYNAME); + version = fread_integer(file_in); + name = fread_fixedstring(file_in, 10); if (version == -29921) fatal(MYNAME ": Uncompress the file first\n"); if (strcmp(name, "TrackMaker") != 0) @@ -454,31 +374,31 @@ gtm_rd_init(const char *fname) xfree(name); /* Header */ - fread_discard(fd, 15); - ws_count = fread_long(fd); - fread_discard(fd, 4); - wp_count = fread_long(fd); - tr_count = fread_long(fd); - rt_count = fread_long(fd); - fread_discard(fd, 16); - im_count = fread_long(fd); - ts_count = fread_long(fd); - fread_discard(fd, 28); - fread_string_discard(fd); - fread_string_discard(fd); - fread_string_discard(fd); - fread_string_discard(fd); + fread_discard(file_in, 15); + ws_count = fread_long(file_in); + fread_discard(file_in, 4); + wp_count = fread_long(file_in); + tr_count = fread_long(file_in); + rt_count = fread_long(file_in); + fread_discard(file_in, 16); + im_count = fread_long(file_in); + ts_count = fread_long(file_in); + fread_discard(file_in, 28); + fread_string_discard(file_in); + fread_string_discard(file_in); + fread_string_discard(file_in); + fread_string_discard(file_in); /* User Grid and Datum */ - fread_discard(fd, 34); - set_datum(fread_integer(fd)); - fread_discard(fd, 22); + fread_discard(file_in, 34); + set_datum(fread_integer(file_in)); + fread_discard(file_in, 22); } static void gtm_rd_deinit(void) { - fclose(fd); + gbfclose(file_in); } static void count_route_waypts(const waypoint *wpt) { rt_count++; } @@ -491,58 +411,58 @@ gtm_wr_init(const char *fname) track_disp_all(NULL, NULL, count_track_waypts); route_disp_all(NULL, NULL, count_route_waypts); - ofd = xfopen(fname, "wb", MYNAME); + file_out = gbfopen_le(fname, "wb", MYNAME); /* little endian */ /* Header */ - fwrite_integer(ofd, 211); - fwrite_fixedstring(ofd, "TrackMaker", 10); - fwrite_byte(ofd, 0); - fwrite_byte(ofd, 0); - fwrite_byte(ofd, 8); - fwrite_byte(ofd, 0); - fwrite_byte(ofd, 0); - fwrite_byte(ofd, 0); - fwrite_byte(ofd, 0); - fwrite_long(ofd, 0); - fwrite_long(ofd, 16777215); - fwrite_long(ofd, waypt_count() ? 4 : 0); /* num waypoint styles */ - fwrite_long(ofd, 0); - fwrite_long(ofd, waypt_count()); /* num waypoints */ - fwrite_long(ofd, tr_count); - fwrite_long(ofd, rt_count); - fwrite_single(ofd, 0); /* maxlon */ - fwrite_single(ofd, 0); /* minlon */ - fwrite_single(ofd, 0); /* maxlat */ - fwrite_single(ofd, 0); /* minlat */ - fwrite_long(ofd, 0); - fwrite_long(ofd, track_count()); /* num tracklog styles */ - fwrite_single(ofd, 0); - fwrite_single(ofd, 0); - fwrite_bool(ofd, 0); - fwrite_bool(ofd, 0); - fwrite_bool(ofd, 0); - fwrite_bool(ofd, 0); - fwrite_bool(ofd, 0); - fwrite_bool(ofd, 0); - fwrite_bool(ofd, 0); - fwrite_bool(ofd, 0); - fwrite_bool(ofd, 0); - fwrite_bool(ofd, 0); - fwrite_string(ofd, "Times New Roman"); - fwrite_string(ofd, ""); - fwrite_string(ofd, ""); - fwrite_string(ofd, ""); + fwrite_integer(file_out, 211); + fwrite_fixedstring(file_out, "TrackMaker", 10); + fwrite_byte(file_out, 0); + fwrite_byte(file_out, 0); + fwrite_byte(file_out, 8); + fwrite_byte(file_out, 0); + fwrite_byte(file_out, 0); + fwrite_byte(file_out, 0); + fwrite_byte(file_out, 0); + fwrite_long(file_out, 0); + fwrite_long(file_out, 16777215); + fwrite_long(file_out, waypt_count() ? 4 : 0); /* num waypoint styles */ + fwrite_long(file_out, 0); + fwrite_long(file_out, waypt_count()); /* num waypoints */ + fwrite_long(file_out, tr_count); + fwrite_long(file_out, rt_count); + fwrite_single(file_out, 0); /* maxlon */ + fwrite_single(file_out, 0); /* minlon */ + fwrite_single(file_out, 0); /* maxlat */ + fwrite_single(file_out, 0); /* minlat */ + fwrite_long(file_out, 0); + fwrite_long(file_out, track_count()); /* num tracklog styles */ + fwrite_single(file_out, 0); + fwrite_single(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_string(file_out, "Times New Roman"); + fwrite_string(file_out, ""); + fwrite_string(file_out, ""); + fwrite_string(file_out, ""); /* User Grid and Datum */ - fwrite_null(ofd, 34); - fwrite_integer(ofd, 217); /* WGS84 */ - fwrite_null(ofd, 22); + fwrite_null(file_out, 34); + fwrite_integer(file_out, 217); /* WGS84 */ + fwrite_null(file_out, 22); } static void gtm_wr_deinit(void) { - fclose(ofd); + gbfclose(file_out); } static void @@ -559,54 +479,54 @@ gtm_read(void) /* Image information */ for (i = 0; i != im_count; i++) { - fread_string_discard(fd); - fread_string_discard(fd); - fread_discard(fd, 30); + fread_string_discard(file_in); + fread_string_discard(file_in); + fread_discard(file_in, 30); } /* Waypoints */ for (i = 0; i != wp_count; i++) { wpt = waypt_new(); - wpt->latitude = fread_double(fd); - wpt->longitude = fread_double(fd); + wpt->latitude = fread_double(file_in); + wpt->longitude = fread_double(file_in); convert_datum(&wpt->latitude, &wpt->longitude); - wpt->shortname = fread_fixedstring(fd, 10); - wpt->description = fread_string(fd); - icon = fread_integer(fd); + wpt->shortname = fread_fixedstring(file_in, 10); + wpt->description = fread_string(file_in); + icon = fread_integer(file_in); if (icon < sizeof(icon_descr)/sizeof(char*)) wpt->icon_descr = icon_descr[icon]; - fread_discard(fd, 1); - wpt->creation_time = fread_long(fd); + fread_discard(file_in, 1); + wpt->creation_time = fread_long(file_in); if (wpt->creation_time) wpt->creation_time += EPOCH89DIFF; - fread_discard(fd, 2); - wpt->altitude = fread_single(fd); + fread_discard(file_in, 2); + wpt->altitude = fread_single(file_in); if (wpt->altitude == unknown_alt_gtm) wpt->altitude = unknown_alt; - fread_discard(fd, 2); + fread_discard(file_in, 2); waypt_add(wpt); } /* Waypoint Styles */ if (wp_count) { for (i = 0; i != ws_count; i++) { - fread_discard(fd, 4); - fread_string_discard(fd); - fread_discard(fd, 24); + fread_discard(file_in, 4); + fread_string_discard(file_in); + fread_discard(file_in, 24); } } /* Tracklogs */ for (i = 0; i != tr_count; i++) { wpt = waypt_new(); - wpt->latitude = fread_double(fd); - wpt->longitude = fread_double(fd); + wpt->latitude = fread_double(file_in); + wpt->longitude = fread_double(file_in); convert_datum(&wpt->latitude, &wpt->longitude); - wpt->creation_time = fread_long(fd); + wpt->creation_time = fread_long(file_in); if (wpt->creation_time) wpt->creation_time += EPOCH89DIFF; - start_new = fread_byte(fd); - wpt->altitude = fread_single(fd); + start_new = fread_byte(file_in); + wpt->altitude = fread_single(file_in); if (wpt->altitude == unknown_alt_gtm) wpt->altitude = unknown_alt; if (start_new || !trk_head) { @@ -622,30 +542,30 @@ gtm_read(void) /* Tracklog styles */ trk_head = first_trk_head; for (i = 0; i != ts_count && i != real_tr_count; i++) { - trk_head->rte_name = fread_string(fd); - fread_discard(fd, 12); + trk_head->rte_name = fread_string(file_in); + fread_discard(file_in, 12); trk_head = (route_head *)QUEUE_NEXT(&trk_head->Q); } /* Routes */ for (i = 0; i != rt_count; i++) { wpt = waypt_new(); - wpt->latitude = fread_double(fd); - wpt->longitude = fread_double(fd); + wpt->latitude = fread_double(file_in); + wpt->longitude = fread_double(file_in); convert_datum(&wpt->latitude, &wpt->longitude); - wpt->shortname = fread_fixedstring(fd, 10); - wpt->description = fread_string(fd); - route_name = fread_string(fd); - icon = fread_integer(fd); + wpt->shortname = fread_fixedstring(file_in, 10); + wpt->description = fread_string(file_in); + route_name = fread_string(file_in); + icon = fread_integer(file_in); if (icon < sizeof(icon_descr)/sizeof(char*)) wpt->icon_descr = icon_descr[icon]; - fread_discard(fd, 1); - start_new = fread_byte(fd); - fread_discard(fd, 6); - wpt->altitude = fread_single(fd); + fread_discard(file_in, 1); + start_new = fread_byte(file_in); + fread_discard(file_in, 6); + wpt->altitude = fread_single(file_in); if (wpt->altitude == unknown_alt_gtm) wpt->altitude = unknown_alt; - fread_discard(fd, 2); + fread_discard(file_in, 2); if (start_new || !rte_head) { rte_head = route_head_alloc(); @@ -672,22 +592,22 @@ int icon_from_descr(const char *descr) static void write_waypt(const waypoint *wpt) { - fwrite_double(ofd, wpt->latitude); - fwrite_double(ofd, wpt->longitude); - fwrite_fixedstring(ofd, wpt->shortname, 10); - fwrite_string(ofd, wpt->description); - fwrite_integer(ofd, icon_from_descr(wpt->icon_descr)); - fwrite_byte(ofd, 3); + fwrite_double(file_out, wpt->latitude); + fwrite_double(file_out, wpt->longitude); + fwrite_fixedstring(file_out, wpt->shortname, 10); + fwrite_string(file_out, wpt->description); + fwrite_integer(file_out, icon_from_descr(wpt->icon_descr)); + fwrite_byte(file_out, 3); if (wpt->creation_time) - fwrite_long(ofd, wpt->creation_time-EPOCH89DIFF); + fwrite_long(file_out, wpt->creation_time-EPOCH89DIFF); else - fwrite_long(ofd, 0); - fwrite_integer(ofd, 0); + fwrite_long(file_out, 0); + fwrite_integer(file_out, 0); if (wpt->altitude == unknown_alt) - fwrite_single(ofd, unknown_alt_gtm); + fwrite_single(file_out, unknown_alt_gtm); else - fwrite_single(ofd, wpt->altitude); - fwrite_integer(ofd, 0); + fwrite_single(file_out, wpt->altitude); + fwrite_integer(file_out, 0); } static void start_rte(const route_head *rte) @@ -698,44 +618,44 @@ static void start_rte(const route_head *rte) static void write_trk_waypt(const waypoint *wpt) { - fwrite_double(ofd, wpt->latitude); - fwrite_double(ofd, wpt->longitude); - fwrite_long(ofd, wpt->creation_time-EPOCH89DIFF); - fwrite_byte(ofd, start_new); + fwrite_double(file_out, wpt->latitude); + fwrite_double(file_out, wpt->longitude); + fwrite_long(file_out, wpt->creation_time-EPOCH89DIFF); + fwrite_byte(file_out, start_new); if (wpt->altitude == unknown_alt) - fwrite_single(ofd, unknown_alt_gtm); + fwrite_single(file_out, unknown_alt_gtm); else - fwrite_single(ofd, wpt->altitude); + fwrite_single(file_out, wpt->altitude); start_new = 0; } static void write_trk_style(const route_head *trk) { - fwrite_string(ofd, trk->rte_name); - fwrite_byte(ofd, 1); - fwrite_long(ofd, 0); - fwrite_single(ofd, 0); - fwrite_byte(ofd, 0); - fwrite_integer(ofd, 0); + fwrite_string(file_out, trk->rte_name); + fwrite_byte(file_out, 1); + fwrite_long(file_out, 0); + fwrite_single(file_out, 0); + fwrite_byte(file_out, 0); + fwrite_integer(file_out, 0); } static void write_rte_waypt(const waypoint *wpt) { - fwrite_double(ofd, wpt->latitude); - fwrite_double(ofd, wpt->longitude); - fwrite_fixedstring(ofd, wpt->shortname, 10); - fwrite_string(ofd, wpt->description); - fwrite_string(ofd, rte_active->rte_name); - fwrite_integer(ofd, icon_from_descr(wpt->icon_descr)); - fwrite_byte(ofd, 3); - fwrite_byte(ofd, start_new); - fwrite_long(ofd, 0); - fwrite_integer(ofd, 0); + fwrite_double(file_out, wpt->latitude); + fwrite_double(file_out, wpt->longitude); + fwrite_fixedstring(file_out, wpt->shortname, 10); + fwrite_string(file_out, wpt->description); + fwrite_string(file_out, rte_active->rte_name); + fwrite_integer(file_out, icon_from_descr(wpt->icon_descr)); + fwrite_byte(file_out, 3); + fwrite_byte(file_out, start_new); + fwrite_long(file_out, 0); + fwrite_integer(file_out, 0); if (wpt->altitude == unknown_alt) - fwrite_single(ofd, unknown_alt_gtm); + fwrite_single(file_out, unknown_alt_gtm); else - fwrite_single(ofd, wpt->altitude); - fwrite_integer(ofd, 0); + fwrite_single(file_out, wpt->altitude); + fwrite_integer(file_out, 0); start_new = 0; } @@ -744,7 +664,7 @@ gtm_write(void) { waypt_disp_all(write_waypt); if (waypt_count()) - fwrite(WAYPOINTSTYLES, 1, sizeof(WAYPOINTSTYLES)-1, ofd); + gbfwrite(WAYPOINTSTYLES, 1, sizeof(WAYPOINTSTYLES)-1, file_out); track_disp_all(start_rte, NULL, write_trk_waypt); track_disp_all(write_trk_style, NULL, NULL); route_disp_all(start_rte, NULL, write_rte_waypt); diff --git a/gtrnctr.c b/gtrnctr.c index b3885131f..07425d417 100644 --- a/gtrnctr.c +++ b/gtrnctr.c @@ -1,7 +1,7 @@ /* Access Garmin Training Center (Forerunner/Foretracker/Edge) data files. - Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + Copyright (C) 2006, 2007 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -127,7 +127,7 @@ gtc_waypt_pr(const waypoint *wpt) gtc_write_xml(1, "\n"); if (wpt->creation_time) { char time_string[100]; - xml_fill_in_time(time_string, wpt->creation_time, + xml_fill_in_time(time_string, wpt->creation_time, wpt->microseconds, XML_LONG_TIME); if (time_string[0]) { gtc_write_xml(0, "\n", @@ -227,7 +227,7 @@ gtc_write(void) if (gtc_least_time) { char time_string[100]; - xml_fill_in_time(time_string, gtc_least_time, XML_LONG_TIME); + xml_fill_in_time(time_string, gtc_least_time, 0, XML_LONG_TIME); gtc_write_xml(1, "\n", time_string); } else { gtc_write_xml(1, "\n"); @@ -271,7 +271,7 @@ void gl_trk_pnt_e(const char *args, const char **unused) void gl_trk_utc(const char *args, const char **unused) { - wpt_tmp->creation_time = xml_parse_time(args); + wpt_tmp->creation_time = xml_parse_time(args, NULL); } void gl_trk_lat(const char *args, const char **unused) diff --git a/hiketech.c b/hiketech.c index c8e0ccced..c5f35b08d 100644 --- a/hiketech.c +++ b/hiketech.c @@ -22,7 +22,7 @@ #include "defs.h" #include "xmlgeneric.h" -static FILE *ofd; +static gbfile *ofd; static waypoint *wpt_tmp; static route_head *trk_head; @@ -94,26 +94,26 @@ hiketech_rd_deinit(void) static void hiketech_wr_init(const char *fname) { - ofd = xfopen(fname, "w", MYNAME); + ofd = gbfopen(fname, "w", MYNAME); } static void hiketech_wr_deinit(void) { - fclose(ofd); + gbfclose(ofd); } static void hiketech_trk_hdr(const route_head *rte) { - fprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); write_optional_xml_entity(ofd, " ", "ident", rte->rte_name); } static void hiketech_trk_tlr(const route_head *rte) { - fprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); } static void @@ -121,52 +121,52 @@ hiketech_print_utc(time_t tm, const char *indent, const char *tag) { char tbuf[80]; strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %I:%M:%S", gmtime(&tm)); - fprintf(ofd, "%s<%s>%s\n",indent,tag,tbuf,tag); + gbfprintf(ofd, "%s<%s>%s\n",indent,tag,tbuf,tag); } static void hiketech_trkpt_pr(const waypoint *waypointp) { - fprintf(ofd, " \n"); + gbfprintf(ofd, " \n"); if (waypointp->creation_time) { hiketech_print_utc(waypointp->creation_time, " ", "utc"); } - fprintf(ofd, " %f\n", waypointp->latitude); - fprintf(ofd, " %f\n", waypointp->longitude); + gbfprintf(ofd, " %f\n", waypointp->latitude); + gbfprintf(ofd, " %f\n", waypointp->longitude); if (waypointp->altitude != unknown_alt) { - fprintf(ofd, " %f\n", + gbfprintf(ofd, " %f\n", waypointp->altitude); } - fprintf(ofd, " \n"); + gbfprintf(ofd, " \n"); } static void hiketech_waypt_pr(const waypoint *wpt) { - fprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); write_xml_entity(ofd, "\t", "ident", wpt->shortname); write_optional_xml_entity(ofd, "\t", "sym", wpt->icon_descr); - fprintf(ofd, "\t%f\n", wpt->latitude); - fprintf(ofd, "\t%f\n", wpt->longitude); + gbfprintf(ofd, "\t%f\n", wpt->latitude); + gbfprintf(ofd, "\t%f\n", wpt->longitude); /* * These probably aren't technicallyconstants, but it's all * we can do for now. */ - fprintf(ofd, "\t\n\t\tFAFFB4\n\t\tFF8000\n\t\n"); - fprintf(ofd, "\n"); + gbfprintf(ofd, "\t\n\t\tFAFFB4\n\t\tFF8000\n\t\n"); + gbfprintf(ofd, "\n"); } static void hiketech_write(void) { - fprintf(ofd, "\n"); - fprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); track_disp_all(hiketech_trk_hdr, hiketech_trk_tlr, hiketech_trkpt_pr); track_disp_all(NULL, NULL, hiketech_trkpt_pr); waypt_disp_all(hiketech_waypt_pr); - fprintf(ofd, "\n"); - fprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); } static diff --git a/holux.c b/holux.c index df475d6c9..a3ffe6baa 100644 --- a/holux.c +++ b/holux.c @@ -32,7 +32,7 @@ History: #include "holux.h" -static FILE *file_in; +static gbfile *file_in; static unsigned char *HxWFile; static short_handle mkshort_handle; static char fOutname[256]; @@ -41,13 +41,13 @@ static char fOutname[256]; static void rd_init(const char *fname) { - file_in = xfopen(fname, "rb", MYNAME); + file_in = gbfopen_le(fname, "rb", MYNAME); } static void rd_deinit(void) { - fclose(file_in); + gbfclose(file_in); } @@ -95,7 +95,7 @@ static void data_read(void) HxWpt = xcalloc(GM100_WPO_FILE_SIZE, 1); /* read the wpo file to the data-array */ - iDataRead = fread( HxWpt, 1, GM100_WPO_FILE_SIZE, file_in ); + iDataRead = gbfread( HxWpt, 1, GM100_WPO_FILE_SIZE, file_in ); if (iDataRead == 0) { diff --git a/hsa_ndv.c b/hsa_ndv.c index bb85c71c7..527bcba63 100644 --- a/hsa_ndv.c +++ b/hsa_ndv.c @@ -36,11 +36,11 @@ static char *routeName = "ROUTENAME"; #define ATTR_OBJECTNAME "OBJNAM" #define ATTR_SHIPNAME "shpnam" -static void readVersion4( FILE* pFile); +static void readVersion4(gbfile* pFile); static void getAttr(const char *data, const char *attr, char **val, char seperator); -static FILE *fd; -static FILE *ofd; +static gbfile *fd; +static gbfile *ofd; static arglist_t hsa_ndv_args[] = { @@ -209,7 +209,7 @@ hsa_ndv_cdata(void *dta, const XML_Char *s, int len) static void hsa_ndv_rd_init(const char *fname) { - fd = xfopen(fname, "r", MYNAME); + fd = gbfopen(fname, "r", MYNAME); psr = XML_ParserCreate(NULL); if (!psr) { @@ -226,26 +226,26 @@ static void hsa_ndv_read(void) { int len; - char buf[MY_CBUF]; - memset(buf, 0, MY_CBUF); + char buf[MY_CBUF + 1]; - while ((len = fread(buf, 1, sizeof(buf), fd))) + while ((len = gbfread(buf, 1, sizeof(buf) - 1, fd))) { char *bad; - buf[len-1] = 0; + buf[len] = '\0'; if (NULL != strstr(buf, "nver=1")) {//its the older format, not xml - fseek(fd, 0, SEEK_SET); + gbfseek(fd, 0, SEEK_SET); readVersion4(fd); break; } //grumble - have to remove \x1f's from sirius attributes - while (NULL != (bad = strchr(buf, '\x1f'))) + bad = buf; + while (NULL != (bad = strchr(bad, '\x1f'))) { *bad = REPLACEMENT_SIRIUS_ATTR_SEPARATOR; } - if (!XML_Parse(psr, buf, len, feof(fd))) { + if (!XML_Parse(psr, buf, len, gbfeof(fd))) { fatal(MYNAME ":Parse error at %d: %s\n", (int) XML_GetCurrentLineNumber(psr), XML_ErrorString(XML_GetErrorCode(psr))); @@ -289,19 +289,19 @@ hsa_ndv_rd_deinit(void) if ( cdatastr ) { xfree(cdatastr); } - fclose(fd); + gbfclose(fd); } static void hsa_ndv_wr_init(const char *fname) { - ofd = xfopen(fname, "w", MYNAME); + ofd = gbfopen(fname, "w", MYNAME); } static void hsa_ndv_wr_deinit(void) { - fclose(ofd); + gbfclose(ofd); } static int legNum = 0; @@ -310,20 +310,20 @@ static void hsa_ndv_waypt_pr(const waypoint *waypointp) { - fprintf(ofd, "\t\t\n"); + gbfprintf(ofd, "\t\t\n"); - fprintf(ofd, "\t\t\twaypnt\n"); + gbfprintf(ofd, "\t\t\twaypnt\n"); //ignore these for now, they are s57 specific // fprintf(ofd, "\t\t\t0\n"); // fprintf(ofd, "\t\t\t1\n"); // fprintf(ofd, "\t\t\t1089009023\n"); - fprintf(ofd, "\t\t\t\n", routeName, waypointp->shortname, legNum, waypointp->description); - fprintf(ofd, "\t\t\t\n", routeName); - fprintf(ofd, "\t\t\t1\n"); - fprintf(ofd, "\t\t\t%lf\n", waypointp->latitude); - fprintf(ofd, "\t\t\t%lf\n", waypointp->longitude); + gbfprintf(ofd, "\t\t\t\n", routeName, waypointp->shortname, legNum, waypointp->description); + gbfprintf(ofd, "\t\t\t\n", routeName); + gbfprintf(ofd, "\t\t\t1\n"); + gbfprintf(ofd, "\t\t\t%lf\n", waypointp->latitude); + gbfprintf(ofd, "\t\t\t%lf\n", waypointp->longitude); - fprintf(ofd, "\t\t\n"); + gbfprintf(ofd, "\t\t\n"); legNum++; } @@ -331,14 +331,14 @@ hsa_ndv_waypt_pr(const waypoint *waypointp) static void hsa_ndv_write(void) { - fprintf(ofd, "\n"); - fprintf(ofd, "\n"); - fprintf(ofd, "\t\n"); - fprintf(ofd, "\t\t1.0000000\n"); - fprintf(ofd, "\t\tROUTENAME\n"); /*TODO: used filename? */ - fprintf(ofd, "\t\t0\n"); + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\t\n"); + gbfprintf(ofd, "\t\t1.0000000\n"); + gbfprintf(ofd, "\t\tROUTENAME\n"); /*TODO: used filename? */ + gbfprintf(ofd, "\t\t0\n"); waypt_disp_all(hsa_ndv_waypt_pr); - fprintf(ofd, "\t\n"); + gbfprintf(ofd, "\t\n"); //later we'll import past tracks and chart objects? // fprintf(ofd, "\t\n"); @@ -347,7 +347,7 @@ hsa_ndv_write(void) // fprintf(ofd, "\t\n"); - fprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); } ff_vecs_t HsaEndeavourNavigator_vecs = { @@ -379,10 +379,10 @@ ff_vecs_t HsaEndeavourNavigator_vecs = { #define INVALID_TIME -1L #define SOUNDARRAY_CHAR 'S' -static int readRecord( FILE* pFile, const char* pRecName, char *recData); -static int readPositionRecord( FILE* pFile, double* lat, double* lng, long* timeStamp); +static int readRecord(gbfile* pFile, const char* pRecName, char *recData); +static int readPositionRecord(gbfile* pFile, double* lat, double* lng, long* timeStamp); -static void readVersion4( FILE* pFile) +static void readVersion4(gbfile* pFile) { while( TRUE ) { @@ -476,12 +476,12 @@ static void readVersion4( FILE* pFile) waypt_add(wpt_tmp); } - fclose(pFile); + gbfclose(pFile); return; } // read a record to a file -static int readRecord( FILE* pFile, const char* pRecName, char *recData) +static int readRecord(gbfile* pFile, const char* pRecName, char *recData) { // get the rec name int len; @@ -490,7 +490,7 @@ static int readRecord( FILE* pFile, const char* pRecName, char *recData) for( len = 0; len < ED_REC_NAME_SIZE; len++) { - int c = fgetc( pFile); + int c = gbfgetc(pFile); // if we hit EOF failed if( c == EOF ) @@ -506,7 +506,7 @@ static int readRecord( FILE* pFile, const char* pRecName, char *recData) // get the rec data for( len = 0; TRUE; len++) { - int c = fgetc( pFile); + int c = gbfgetc( pFile); // if we hit EOF failed if( c == EOF ) @@ -526,7 +526,7 @@ static int readRecord( FILE* pFile, const char* pRecName, char *recData) } // read position -static int readPositionRecord( FILE* pFile, double* lat, double* lng, +static int readPositionRecord(gbfile* pFile, double* lat, double* lng, long* timeStamp) { // read the lat record diff --git a/html.c b/html.c index cadda3066..ba8390d83 100644 --- a/html.c +++ b/html.c @@ -175,7 +175,7 @@ html_disp(const waypoint *wpt) logpart = xml_findfirst( curlog, "groundspeak:date" ); if ( logpart ) { - logtime = xml_parse_time( logpart->cdata ); + logtime = xml_parse_time( logpart->cdata, NULL); logtm = localtime( &logtime ); if ( logtm ) { fprintf( file_out, diff --git a/igc.c b/igc.c index f51397550..f94a5a29f 100644 --- a/igc.c +++ b/igc.c @@ -305,7 +305,7 @@ static void data_read(void) case rec_fix: // Date must appear in file before the first fix record if (date < 1000000L) { - fatal(MYNAME ": bad date %ld\n", date); + fatal(MYNAME ": bad date %d\n", (int)date); } // Create a track for pressure altitude waypoints if (!pres_head) { diff --git a/ignrando.c b/ignrando.c index 98b449bfa..7a76b57bb 100644 --- a/ignrando.c +++ b/ignrando.c @@ -1,8 +1,8 @@ /* - Support for IGN Rando track files, + Support for IGN Rando track files. - Copyright (C) 2005 Olaf Klein, o.b.klein@gpsbabel.org + Copyright (C) 2005,2006 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -33,7 +33,7 @@ #define MYNAME "IGNRando" -static FILE *fout; +static gbfile *fout; static route_head *track; static waypoint *wpt; @@ -189,50 +189,18 @@ ignr_read(void) /* write support */ -static void -ignr_fprintf(FILE *f, const char *fmt, ...) -{ - char buff[256]; - char *temp = buff; - va_list args; - int i; - - va_start(args, fmt); - - i = vsnprintf(buff, sizeof(buff), fmt, args); - if (i >= (int) sizeof(buff)) - { - temp = xmalloc(i + 1); - i = vsnprintf(temp, i + 1, fmt, args); - } - if (i < 0) - { - fatal(MYNAME ": error in vsnprintf.\n"); - } - else if (i > 0) - { - char eol = temp[i - 1]; - if (eol == '\n') i--; - fwrite(temp, 1, i, f); - if (eol == '\n') fprintf(f, "\r\n"); - } - - if (temp != buff) xfree(temp); - va_end(args); -} - /* callbacks registered in ignr_vecs */ static void ignr_rw_init(const char *fname) { - fout = xfopen(fname, "wb", MYNAME); + fout = gbfopen(fname, "w", MYNAME); } static void ignr_rw_deinit(void) { - fclose(fout); + gbfclose(fout); } static void @@ -242,11 +210,11 @@ ignr_write_track_hdr(const route_head *track) if (track_num != track_index) return; - ignr_fprintf(fout, "\t\n"); - ignr_fprintf(fout, "\t\t%d\n", track->rte_waypt_ct); + gbfprintf(fout, "\t\n"); + gbfprintf(fout, "\t\t%d\n", track->rte_waypt_ct); if (track->rte_desc != NULL) - ignr_fprintf(fout, "\t\t%s\n", track->rte_desc); - ignr_fprintf(fout, "\t\n"); + gbfprintf(fout, "\t\t%s\n", track->rte_desc); + gbfprintf(fout, "\t\n"); } static void @@ -259,11 +227,11 @@ ignr_write_waypt(const waypoint *wpt) { if (track_num != track_index) return; - ignr_fprintf(fout, "\t\n"); - ignr_fprintf(fout, "\t\t%3.6f,%3.6f\n", wpt->latitude, wpt->longitude); + gbfprintf(fout, "\t\n"); + gbfprintf(fout, "\t\t%3.6f,%3.6f\n", wpt->latitude, wpt->longitude); if (wpt->altitude != unknown_alt) - ignr_fprintf(fout, "\t\t%3.6f\n", wpt->altitude); - ignr_fprintf(fout, "\t\n"); + gbfprintf(fout, "\t\t%3.6f\n", wpt->altitude); + gbfprintf(fout, "\t\n"); } static void @@ -287,20 +255,20 @@ ignr_write(void) now = current_time(); tm = *localtime(&now); - ignr_fprintf(fout, "\n"); - ignr_fprintf(fout, "\n"); - ignr_fprintf(fout, "\t\n"); - ignr_fprintf(fout, "\t\t1.1\n"); - ignr_fprintf(fout, "\t\tIHA03AA\n"); + gbfprintf(fout, "\n"); + gbfprintf(fout, "\n"); + gbfprintf(fout, "\t\n"); + gbfprintf(fout, "\t\t1.1\n"); + gbfprintf(fout, "\t\tIHA03AA\n"); strftime(buff, sizeof(buff), "%d/%m/%Y", &tm); - ignr_fprintf(fout, "\t\t%s\n", buff); + gbfprintf(fout, "\t\t%s\n", buff); strftime(buff, sizeof(buff), "%H:%M:%S", &tm); - ignr_fprintf(fout, "\t\t%s\n", buff); + gbfprintf(fout, "\t\t%s\n", buff); - ignr_fprintf(fout, "\t\n"); + gbfprintf(fout, "\t\n"); track_disp_all(ignr_write_track_hdr, ignr_write_track_trl, ignr_write_waypt); - ignr_fprintf(fout, "\n"); + gbfprintf(fout, "\n"); } ff_vecs_t ignr_vecs = { diff --git a/internal_styles.c b/internal_styles.c index 34b1caf1c..17d3078eb 100644 --- a/internal_styles.c +++ b/internal_styles.c @@ -437,7 +437,10 @@ static char gpsdrivetrack[] = "IFIELD LAT_DECIMAL, \"\", \"%10.6f\"\n" "IFIELD LON_DECIMAL, \"\", \"%10.6f\"\n" "IFIELD ALT_METERS, \"\", \"%10.0f\"\n" -"IFIELD GMT_TIME, \"\", \"%a %b %d %T %Y\"\n" +"# Reports are that this format stores in local time, not GMT as \n" +"# originally thought.\n" +"# IFIELD GMT_TIME, \"\", \"%a %b %d %H:%M:%S %Y\"\n" +"IFIELD LOCAL_TIME, \"\", \"%a %b %d %H:%M:%S %Y\"\n" ; static char gpsman[] = "# gpsbabel XCSV style file\n" @@ -475,6 +478,54 @@ static char gpsman[] = "# gpsman.c likes mkshort len = 8, whitespace = 0.\n" ; +static char kompass_tk[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: Kompass / Deutscher Alpenverein (DAV) Waypoints\n" +"# Author: Olaf Klein\n" +"# Date: 01/10/2007\n" +"#\n" +"# \n" +"DESCRIPTION Kompass (DAV) Track (.tk)\n" +"DATATYPE TRACK\n" +"EXTENSION wp\n" +"FIELD_DELIMITER COMMA\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS ,\"\n" +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"#\n" +"IFIELD LAT_DECIMAL, \"\", \"%.7f\"\n" +"IFIELD LON_DECIMAL, \"\", \"%.7f\"\n" +; +static char kompass_wp[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: Kompass / Deutscher Alpenverein (DAV) Waypoints\n" +"# Author: Olaf Klein\n" +"# Date: 01/10/2007\n" +"#\n" +"# \n" +"DESCRIPTION Kompass (DAV) Waypoints (.wp)\n" +"DATATYPE WAYPOINT\n" +"EXTENSION wp\n" +"ENCODING UTF-8\n" +"FIELD_DELIMITER SEMICOLON\n" +"RECORD_DELIMITER CRNEWLINE\n" +"BADCHARS ,\"\n" +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"#\n" +"IFIELD SHORTNAME, \"\", \"%s\"\n" +"IFIELD LON_DECIMAL, \"\", \"%.7f\"\n" +"IFIELD LAT_DECIMAL, \"\", \"%.7f\"\n" +"IFIELD ALT_METERS, \"\", \"%.0f\"\n" +"IFIELD LOCAL_TIME,\"\",\"%d.%m.%Y %H:%M:%S\"\n" +"IFIELD CONSTANT, \"Icons\\Wegpunkt grün.bmp\", \"%s\"\n" +"IFIELD IGNORE, \"\", \"%s\"\n" +"IFIELD CONSTANT, \"1\", \"%s\" # unknown\n" +"IFIELD DESCRIPTION, \"\", \"%s\"\n" +; static char ktf2[] = "# gpsbabel XCSV style file\n" "#\n" @@ -889,6 +940,8 @@ static char tabsep[] = "IFIELD PATH_DISTANCE_KM, \"\", \"%f\"\n" "IFIELD GEOCACHE_PLACER,\"\",\"%s\"\n" "IFIELD YYYYMMDD_TIME,\"\",\"%ld\"\n" +"IFIELD GEOCACHE_HINT, \"\", \"%s\"\n" +"IFIELD GEOCACHE_LAST_FOUND, \"\", \"%d\"\n" ; static char xmap2006[] = "# gpsbabel XCSV style file\n" @@ -995,8 +1048,8 @@ static char xmapwpt[] = "IFIELD IGNORE, \"\", \"%-.31s\"\n" "IFIELD DESCRIPTION, \"\", \"%-.78s\"\n" ; -style_vecs_t style_list[] = {{ "xmapwpt", xmapwpt } , { "xmap", xmap } , { "xmap2006", xmap2006 } , { "tabsep", tabsep } , { "sportsim", sportsim } , { "saplus", saplus } , { "s_and_t", s_and_t } , { "openoffice", openoffice } , { "nima", nima } , { "mxf", mxf } , { "mapconverter", mapconverter } , { "kwf2", kwf2 } , { "ktf2", ktf2 } , { "gpsman", gpsman } , { "gpsdrivetrack", gpsdrivetrack } , { "gpsdrive", gpsdrive } , { "geonet", geonet } , { "garmin_poi", garmin_poi } , { "garmin301", garmin301 } , { "fugawi", fugawi } , { "dna", dna } , { "custom", custom } , { "cup", cup } , { "csv", csv } , { "cambridge", cambridge } , { "arc", arc } , {0,0}}; -size_t nstyles = 26; +style_vecs_t style_list[] = {{ "xmapwpt", xmapwpt } , { "xmap", xmap } , { "xmap2006", xmap2006 } , { "tabsep", tabsep } , { "sportsim", sportsim } , { "saplus", saplus } , { "s_and_t", s_and_t } , { "openoffice", openoffice } , { "nima", nima } , { "mxf", mxf } , { "mapconverter", mapconverter } , { "kwf2", kwf2 } , { "ktf2", ktf2 } , { "kompass_wp", kompass_wp } , { "kompass_tk", kompass_tk } , { "gpsman", gpsman } , { "gpsdrivetrack", gpsdrivetrack } , { "gpsdrive", gpsdrive } , { "geonet", geonet } , { "garmin_poi", garmin_poi } , { "garmin301", garmin301 } , { "fugawi", fugawi } , { "dna", dna } , { "custom", custom } , { "cup", cup } , { "csv", csv } , { "cambridge", cambridge } , { "arc", arc } , {0,0}}; +size_t nstyles = 28; #else /* CSVFMTS_ENABLED */ style_vecs_t style_list[] = {{0,0}}; size_t nstyles = 0; diff --git a/jeeps/.cvsignore b/jeeps/.cvsignore new file mode 100644 index 000000000..f3c7a7c5d --- /dev/null +++ b/jeeps/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/jeeps/gpsapp.c b/jeeps/gpsapp.c index 104f535c7..3190681fd 100644 --- a/jeeps/gpsapp.c +++ b/jeeps/gpsapp.c @@ -3467,6 +3467,9 @@ drain_run_cmd(gpsdevh *fd) break; } } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); return 0; } @@ -3793,6 +3796,10 @@ int32 GPS_A301_Send(const char *port, GPS_PTrack *trk, int32 n) GPS_D301_Send(data,trk[i]); len = 21; break; + case pD304: + GPS_D304_Send(data,trk[i]); + len = 26; + break; default: GPS_Error("A301_Send: Unknown track protocol"); return PROTOCOL_ERROR; @@ -4192,6 +4199,36 @@ void GPS_D301_Send(UC *data, GPS_PTrack trk) return; } +void GPS_D304_Send(UC *data, GPS_PTrack trk) +{ + UC *p; + + p = data; + GPS_A300_Encode(p,trk); + p = data+12; + + GPS_Util_Put_Float(p,trk->alt); + p+=sizeof(float); + + GPS_Util_Put_Float(p, (const float) 1.0e25); + p+=sizeof(float); + + /* Not really clear if the members below makes sense to write or not */ + + *p = trk->heartrate; + p+=sizeof(char); + + *p = trk->cadence; + p+=sizeof(char); + + *p = trk->cadence > 0 ? trk->cadence : 0xff; + p+=sizeof(char); + + *p = trk->tnew; + + return; +} + /* @func GPS_D310_Send ************************************************** @@ -5967,18 +6004,25 @@ int32 GPS_A800_Get(gpsdevh **fd, GPS_PPvt_Data *packet) GPS_PPacket tra; GPS_PPacket rec; - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) return MEMORY_ERROR; - if(!GPS_Packet_Read(*fd, &rec)) + if(!GPS_Packet_Read(*fd, &rec)) { + GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); return gps_errno; + } - if(!GPS_Send_Ack(*fd, &tra, &rec)) + if(!GPS_Send_Ack(*fd, &tra, &rec)) { + GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); return gps_errno; + } if (rec->type != LINK_ID[gps_link_type].Pid_Pvt_Data) { + GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); return 0; } @@ -5989,6 +6033,8 @@ int32 GPS_A800_Get(gpsdevh **fd, GPS_PPvt_Data *packet) break; default: GPS_Error("A800_GET: Unknown pvt protocol"); + GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); return PROTOCOL_ERROR; } diff --git a/jeeps/gpsapp.h b/jeeps/gpsapp.h index 2d9ead9c1..ee6416847 100644 --- a/jeeps/gpsapp.h +++ b/jeeps/gpsapp.h @@ -34,6 +34,7 @@ void GPS_D310_Get(GPS_PTrack *trk, UC *s); void GPS_D311_Get(GPS_PTrack *trk, UC *s); void GPS_D300_Send(UC *data, GPS_PTrack trk); void GPS_D301_Send(UC *data, GPS_PTrack trk); +void GPS_D304_Send(UC *data, GPS_PTrack trk); void GPS_D310_Send(UC *data, GPS_PTrack trk, int32 *len); int32 GPS_A400_Get(const char *port, GPS_PWay **way); diff --git a/jeeps/gpslibusb.c b/jeeps/gpslibusb.c index 225f35a47..184713446 100644 --- a/jeeps/gpslibusb.c +++ b/jeeps/gpslibusb.c @@ -104,6 +104,7 @@ gusb_teardown(gpsdevh *dh) if (udev) { usb_release_interface(udev, 0); usb_close(udev); + xfree(dh); udev = NULL; } return 0; diff --git a/jeeps/gpsserial.c b/jeeps/gpsserial.c index 78896bfe8..4e90f0939 100644 --- a/jeeps/gpsserial.c +++ b/jeeps/gpsserial.c @@ -305,6 +305,7 @@ void GPS_Serial_Error(const char *mb, ...) s = msg + b; *s++ = ':'; *s++ = ' '; + *s++ = '\0'; // FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, // GetLastError(), 0, s, sizeof(msg) - b - 2, 0 ); diff --git a/jeeps/gpsusbstub.c b/jeeps/gpsusbstub.c index b42d7091a..060bab422 100644 --- a/jeeps/gpsusbstub.c +++ b/jeeps/gpsusbstub.c @@ -24,7 +24,7 @@ #include "../defs.h" #if !HAVE_LIBUSB -const char no_usb[] = "USB suport is not available in this build.\n"; +const char no_usb[] = "USB support is not available in this build.\n"; int gusb_init(const char *portname) diff --git a/jeeps/gpsusbwin.c b/jeeps/gpsusbwin.c index 1fe48959f..fd7a5cec5 100644 --- a/jeeps/gpsusbwin.c +++ b/jeeps/gpsusbwin.c @@ -161,6 +161,11 @@ HANDLE * garmin_usb_start(HDEVINFO* hdevinfo, SP_DEVICE_INTERFACE_DATA *infodata usb_handle = CreateFile(pdd->DevicePath, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL ); if (usb_handle == INVALID_HANDLE_VALUE) { + if (GetLastError() == ERROR_ACCESS_DENIED) { + warning( +"Exclusive access is denied. It's likely that something else such as\n" +"Nroute, Spanner, Google Earth, or GPSGate already has control of the device\n"); + } GPS_Serial_Error("(usb) CreateFile on '%s' failed", pdd->DevicePath); return NULL; } diff --git a/kml.c b/kml.c index aad687678..c544a041f 100644 --- a/kml.c +++ b/kml.c @@ -1,7 +1,7 @@ /* Support for Google Earth & Keyhole "kml" format. - Copyright (C) 2005, 2006 Robert Lipe, robertlipe@usa.net + Copyright (C) 2005, 2006, 2007 Robert Lipe, robertlipe@usa.net Updates by Andrew Kirmse, akirmse at google.com This program is free software; you can redistribute it and/or modify @@ -22,6 +22,10 @@ #include "defs.h" #include "xmlgeneric.h" +#ifdef __WIN32__ +# include +#endif + // options static char *opt_deficon = NULL; static char *opt_export_lines = NULL; @@ -288,15 +292,8 @@ kml_wr_deinit(void) if (posnfilenametmp) { #if __WIN32__ - /* - * This is gross. - * Windows does not offer an atomic rename; we must - * explictly remove the destination here which exposes - * a window where a polled reader of this file could find - * the file to be missing. Windows readers will simply - * have to retry on this case. - */ - unlink(posnfilename); + MoveFileEx(posnfilenametmp, posnfilename, + MOVEFILE_REPLACE_EXISTING); #endif rename(posnfilenametmp, posnfilename); xfree(posnfilenametmp); @@ -394,7 +391,7 @@ static void kml_output_timestamp(const waypoint *waypointp) { char time_string[64]; if (waypointp->creation_time) { - xml_fill_in_time(time_string, waypointp->creation_time, XML_LONG_TIME); + xml_fill_in_time(time_string, waypointp->creation_time, waypointp->microseconds, XML_LONG_TIME); if (time_string[0]) { kml_write_xml(0, "%s\n", time_string); @@ -471,9 +468,9 @@ void kml_output_trkdescription(const route_head *header, computed_trkdata *td) if (td->start && td->end) { char time_string[64]; kml_write_xml(1, "\n"); - xml_fill_in_time(time_string, td->start, XML_LONG_TIME); + xml_fill_in_time(time_string, td->start, 0, XML_LONG_TIME); kml_write_xml(0, "%s\n", time_string); - xml_fill_in_time(time_string, td->end, XML_LONG_TIME); + xml_fill_in_time(time_string, td->end, 0, XML_LONG_TIME); kml_write_xml(0, "%s\n", time_string); kml_write_xml(-1, "\n"); } @@ -679,8 +676,13 @@ static void kml_waypt_pr(const waypoint *waypointp) else fputs(odesc, ofd); - if (!global_opts.no_smart_icons && - waypointp->gc_data.diff && waypointp->gc_data.terr) { + /* It's tempting to conditionalize this on smart_names, but + * KML is so robust that it makes sense to just always do + * this for geocaches. (Plus the convenience of being able + * to do a drag-n-drop into Earth without extra option is a + * win.) + */ + if (waypointp->gc_data.diff && waypointp->gc_data.terr) { if (waypointp->gc_data.placer) { char *p = xml_entitize(waypointp->gc_data.placer); fprintf(ofd, " by %s]]>", p); @@ -716,7 +718,7 @@ static void kml_waypt_pr(const waypoint *waypointp) kml_write_xml(-1, "\n"); kml_write_xml(-1, "\n"); - } else if (!global_opts.no_smart_icons && waypointp->gc_data.diff && waypointp->gc_data.terr) { + } else if (waypointp->gc_data.diff && waypointp->gc_data.terr) { char *is = kml_lookup_gc_icon(waypointp); kml_write_xml(1, "